2014-12-04 64 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; 
}