java - 增量读取大文件的最快方法

标签 java file-io nio

当给定一个 MAX_BUFFER_SIZE 的缓冲区,以及一个远远超过它的文件时,如何:

  1. 以 MAX_BUFFER_SIZE 的 block 读取文件?
  2. 尽快完成

我尝试使用 NIO

    RandomAccessFile aFile = new RandomAccessFile(fileName, "r");
    FileChannel inChannel = aFile.getChannel();

    ByteBuffer buffer = ByteBuffer.allocate(CAPARICY);

    int bytesRead = inChannel.read(buffer);

    buffer.flip();

        while (buffer.hasRemaining()) {
            buffer.get();
        }

        buffer.clear();
        bytesRead = inChannel.read(buffer);

    aFile.close();

和常规 IO

    InputStream in = new FileInputStream(fileName);

    long length = fileName.length();

    if (length > Integer.MAX_VALUE) {
        throw new IOException("File is too large!");
    }

    byte[] bytes = new byte[(int) length];

    int offset = 0;

    int numRead = 0;

    while (offset < bytes.length
            && (numRead = in.read(bytes, offset, bytes.length - offset)) >= 0) {
        offset += numRead;
    }

    if (offset < bytes.length) {
        throw new IOException("Could not completely read file " + fileName);
    }

    in.close();

事实证明,常规 IO 在做同样事情时的速度大约是 NIO 的 100 倍。我错过了什么吗?这是预期的吗?有没有更快的方法来读取缓冲区 block 中的文件?

最终我正在处理一个大文件,我没有内存可以一次读取它。相反,我想以 block 的形式逐步阅读它,然后用于处理。

最佳答案

如果你想让你的第一个例子更快

FileChannel inChannel = new FileInputStream(fileName).getChannel();
ByteBuffer buffer = ByteBuffer.allocateDirect(CAPACITY);

while(inChannel.read(buffer) > 0)
    buffer.clear(); // do something with the data and clear/compact it.

inChannel.close();

如果你想让它更快。

FileChannel inChannel = new RandomAccessFile(fileName, "r").getChannel();
MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
// access the buffer as you wish.
inChannel.close();

对于最大为 2 GB 的文件,这可能需要 10 到 20 微秒。

关于java - 增量读取大文件的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9046820/

相关文章:

java - SelectionKey 实例调用 interestOps(0) 是什么意思?

java - 在 Java 中自定义默认的 AbstractColorChooserPanel

java - JPopupMenu 中的居中 JLabel

c - 读取字符 0x1A 时发生文件结尾

C++追加到字符串并写入文件

java - Android DatagramChannel.register() block 执行

java - 向 JPanel 添加椭圆形

java - GSON解析动态JSON字段

perl - 有没有办法在 Perl 中创建在创建时锁定的文件?

java - 如果您可以捕获异常并稍后重试,那么锁定文件有什么意义呢?