2014-12-04 101 views
0

我所擁有的文件比較的布爾方法。它成爲bb的一部分並且平等地檢查。 如果零件相等 - 得到下一個塊。如果位置(點)>文件大小和所有塊相等 - 則返回true。 適用於小文件(10MB),但在大文件上有問題。字節緩衝區的等於

private static boolean getFiles(File file1, File file2) throws IOException { 
    FileChannel channel1 = new FileInputStream(file1).getChannel(); 
    FileChannel channel2 = new FileInputStream(file2).getChannel(); 
    int SIZE; 
    MappedByteBuffer buffer1, buffer2; 
    for (int point = 0; point < channel1.size(); point += SIZE) { 
     SIZE = (int) Math.min((4096*1024), channel1.size() - point); 
     buffer1 = channel1.map(FileChannel.MapMode.READ_ONLY, point, SIZE); 
     buffer2 = channel2.map(FileChannel.MapMode.READ_ONLY, point, SIZE); 
     if (!buffer1.equals(buffer2)) { 
      return false; 
     } 
    } 
    return true; 
} 

我該如何修改它?改變塊的大小?

+0

我會嘗試在可能的範圍內16-128k或小這麼多塊......沒有更多的,我能想到的嘗試: ) – xpa1492 2014-12-04 09:02:45

+0

看到這個http://stackoverflow.com/questions/964332/java-large-files-disk-io - 性能 – Dexter 2014-12-04 10:13:54

+0

問題是'MappedByteBuffer'沒有釋放資源的方法,而是依賴於可能異步和延遲的終止,所以當在循環中分配緩衝區時,即使在舊緩衝區中可能會遇到「OutOfMemoryError」超出範圍。我認爲這是Java API的設計錯誤,但是,偶爾調用'System.gc()'可能會解決問題。 – Holger 2015-03-18 14:43:33

回答

0

如果文件2比文件1,你會得到嘗試的文件2結束後讀取數據時的錯誤,在該行小:

buffer2 = channel2.map(FileChannel.MapMode.READ_ONLY, point, SIZE); 
0

除此之外,你錯過了幾個角落的情況下,我使用直接分配的字節緩衝區應該是比你的方法:)更快

public static void main (String [] args) throws IOException { 

    final File file1 = new File(args[0]); 
    final File file2 = new File(args[1]); 

    //check if the files exist and are not blank 
    if(!file1.exists() || !file2.exists() || 
     file1.length() == 0 || file2.length() == 0) { 
     System.out.println("ILLEGAL FILES"); 
     return; 
    } 

    //if the length of the files is not same they are obviously not the same files 
    if(file1.length() != file2.length()) { 
     System.out.println("DIFFERENT SIZE"); 
     return; 
    } 

    final FileChannel channel1 = new FileInputStream(file1).getChannel(); 
    final FileChannel channel2 = new FileInputStream(file2).getChannel(); 

    //DirectByteBuffers for faster IO 
    final ByteBuffer byteBuffer1 = ByteBuffer.allocateDirect(128 * 1024); 
    final ByteBuffer byteBuffer2 = ByteBuffer.allocateDirect(128 * 1024); 

    System.out.println("Starting Compare"); 

    while(true) { 

     int read1, read2 =0; 
     read1 = channel1.read(byteBuffer1); 
     if(read1 == -1) break; 

     while (read2 < read1 && read2 >= 0) { 
      read2 += (channel2.read(byteBuffer2)); 
     } 
     byteBuffer1.flip();byteBuffer2.flip(); 
     if(byteBuffer1.compareTo(byteBuffer2) != 0) { 
      System.out.println("NOT SAME"); 
      return; 
     } 

     byteBuffer1.clear(); 
     byteBuffer2.clear(); 
    } 
    System.out.println("SAME :)"); 
    return; 
}