【问题标题】:ByteBuffer's equalsByteBuffer 的等于
【发布时间】:2014-12-04 19:06:39
【问题描述】:

我有一个文件比较的布尔方法。它是 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;
}

如何修改?改变块的大小?

【问题讨论】:

  • 我会尝试更小的块,可能在 16-128k 左右的范围内......我想不出更多的尝试:)
  • 问题是MappedByteBuffer 没有释放资源的方法,相反,它依赖于可能异步发生并延迟的终结,因此在循环中分配缓冲区时可能会遇到OutOfMemoryError即使旧缓冲区超出范围。我认为这是 Java API 的设计错误,但偶尔调用 System.gc() 可能会解决问题。

标签: java equals memory-mapped-files bytebuffer


【解决方案1】:

如果 file2 小于 file1,则在 file2 结束后尝试读取数据时会出现错误,在这一行:

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

【讨论】:

    【解决方案2】:

    除了你错过的几个极端情况之外,我使用直接分配字节缓冲区应该比你的方法更快:)

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 2010-11-30
      • 2014-12-23
      • 2019-04-10
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多