2014-12-04 2 views
0

У меня есть логический метод сравнения файлов. Он получает часть bb и проверяется на равных. Если части равны - получите следующий блок. Если позиция (точка)> размер файла и все блоки равны - верните true. Работает с небольшими файлами (10 МБ), но есть проблемы на большом.ByteBuffer's equals

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

+0

см. Это http://stackoverflow.com/questions/964332/java-large-files-disk-io -performance – Dexter

+0

Проблема заключается в том, что 'MappedByteBuffer' не имеет метода для освобождения ресурса, вместо этого он полагается на завершение, которое может происходить асинхронно и отсрочено, поэтому при распределении буферов в цикле вы можете запускать« OutOfMemoryError », даже когда старые буферы выходят за рамки. Я считаю это ошибкой дизайна Java API, но иногда вызов 'System.gc()' иногда может решить проблему. – Holger

ответ

0

если file2 меньше file1 вы получите сообщение об ошибке при попытке чтения данных после окончания file2, в этой строке:

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; 
} 
Смежные вопросы