小编典典

使用Java NIO读取和写入大文件

java

如何使用Java NIO框架有效地从大文件读取并将大数据写入文件。

我工作ByteBuffer,并FileChannel和曾尝试类似如下:

public static void main(String[] args) 
{
    String inFileStr = "screen.png";
    String outFileStr = "screen-out.png";
    long startTime, elapsedTime; 
    int bufferSizeKB = 4;
    int bufferSize = bufferSizeKB * 1024;

    // Check file length
    File fileIn = new File(inFileStr);
    System.out.println("File size is " + fileIn.length() + " bytes");
    System.out.println("Buffer size is " + bufferSizeKB + " KB");
    System.out.println("Using FileChannel with an indirect ByteBuffer of " + bufferSizeKB + " KB");

    try (   FileChannel in = new FileInputStream(inFileStr).getChannel();
            FileChannel out = new FileOutputStream(outFileStr).getChannel() ) 
    {
        // Allocate an indirect ByteBuffer
        ByteBuffer bytebuf = ByteBuffer.allocate(bufferSize);

        startTime = System.nanoTime();

        int bytesCount = 0;
        // Read data from file into ByteBuffer
        while ((bytesCount = in.read(bytebuf)) > 0) { 
            // flip the buffer which set the limit to current position, and position to 0.
            bytebuf.flip();
            out.write(bytebuf); // Write data from ByteBuffer to file
            bytebuf.clear(); // For the next read
        }

        elapsedTime = System.nanoTime() - startTime;
        System.out.println("Elapsed Time is " + (elapsedTime / 1000000.0) + " msec");
    } 
    catch (IOException ex) {
        ex.printStackTrace();
    }
}

谁能告诉我,如果我的文件大小超过2 GB,我应该遵循相同的步骤吗?

如果大量的书面操作,我想在写作时做类似的事情,该怎么办?


阅读 539

收藏
2020-11-30

共1个答案

小编典典

请注意,您可以Files.copy(Paths.get(inFileStr),Paths.get(outFileStr), StandardCopyOption.REPLACE_EXISTING)像示例代码那样简单地用于复制文件,只是速度更快,而且仅一行代码。

否则,如果您已经打开了两个文件通道,则可以使用
in.transferTo(0, in.size(), out)将该in通道的全部内容传输到该out通道。请注意,此方法允许在源文件中指定一个范围,该范围将被传输到目标通道的当前位置(最初为零),并且还有一种相反的方法,即out.transferFrom(in, 0, in.size())从源通道的当前位置传输数据到目标文件中的绝对范围。

它们在一起,可以有效地进行几乎所有可以想象到的简单的批量传输,而无需将数据复制到Java侧缓冲区中。如果那不能解决您的需求,则您必须在问题中更加具体。

顺便说一句,从Java
7开始,您可以直接打开一个FileChannel不带FileInputStream/
FileOutputStream绕行的位置。

2020-11-30