使用JavaNIO读写大型文件

使用JavaNIO读写大型文件,java,nio,file-processing,Java,Nio,File Processing,如何使用javanio框架有效地读取大文件并将大容量数据写入文件 我正在使用ByteBuffer和FileChannel并尝试了以下方法: public static void main(String[] args) { String inFileStr = "screen.png"; String outFileStr = "screen-out.png"; long startTime, elapsedTime; int bufferSizeKB = 4;

如何使用
javanio
框架有效地读取大文件并将大容量数据写入文件

我正在使用
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();
    }
}
有人能告诉我,如果我的文件大小超过2GB,我应该遵循同样的程序吗

如果编写操作是批量的,那么在编写时我想做的类似事情应该遵循什么

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
    }
您的复制循环不正确。应该是:

while ((bytesCount = in.read(bytebuf)) > 0 || bytebuf.position() > 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.compact(); // For the next read
    }
有人能告诉我,如果我的文件大小超过2GB,我应该遵循同样的程序吗

对。文件大小没有任何区别

您的复制循环不正确。应该是:

while ((bytesCount = in.read(bytebuf)) > 0 || bytebuf.position() > 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.compact(); // For the next read
    }
有人能告诉我,如果我的文件大小超过2GB,我应该遵循同样的程序吗


对。文件大小没有任何区别。

请注意,您可以像示例代码那样简单地使用复制文件,只需一行代码就可以更快地复制文件

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

总之,它们允许以有效的方式进行几乎所有可以想象的非平凡批量传输,而无需将数据复制到Java端缓冲区中。如果这不能解决你的需要,你必须在你的问题上更加具体


顺便说一句,您可以不使用Java 7以来的
FileInputStream
/
FileOutputStream
绕道。请注意,您可以像示例代码那样简单地使用来复制文件,只需一行代码,速度可能会更快

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

总之,它们允许以有效的方式进行几乎所有可以想象的非平凡批量传输,而无需将数据复制到Java端缓冲区中。如果这不能解决你的需要,你必须在你的问题上更加具体


顺便说一句,您可以不使用Java 7以来的
FileInputStream
/
FileOutputStream
迂回路线。

您是在尝试处理中间的数据,还是只想复制它?“如果类似的事情我想做”是什么意思?您是在尝试处理中间的数据,或者您只是想复制它?如果“我想做类似的事情”是什么意思?如果文件大小很大,此更改将产生怎样的影响?它将确保不丢失不完整的写入,并刷新最终的读取。此代码适用于从零到更大的任何文件大小。如果文件大小很大,此更改将产生怎样的影响?它将确保不丢失不完整的写入,并刷新最后的片段读取。此代码适用于从零开始的任何文件大小。