gpt4 book ai didi

java - 使用 FileChannels 在 Java 中连接大文件的方法更有效

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:01:33 26 4
gpt4 key购买 nike

我想找出我提出的用 Java 连接我的文本文件的两种方法中哪种方法更好。如果有人有一些见解,他们可以分享内核级别发生的事情,解释这些写入 FileChannel 的方法之间的区别,我将不胜感激。

根据我从文档和其他 Stack Overflow 对话中了解到的情况,allocateDirect 直接在驱动器上分配空间,并且主要避免使用 RAM。我担心如果 File infile 很大(比如 1GB),使用 allocateDirect 创建的 ByteBuffer 可能会溢出或无法分配。在我们软件开发的这一点上,我保证文件不会大于 2 GB;但 future 有可能达到 10 或 20GB。

我观察到 transferFrom 循环从不超过一次循环...所以它似乎一次成功地写入了整个 infile;但我还没有用大于 60MB 的文件测试过它。但是我循环了,因为文档指定不能保证一次写入多少。由于 transferFrom 在我的系统上只能接受一个 int32 作为其计数参数,我将无法一次指定超过 2GB 的传输...同样,内核专业知识将帮助我理解。

在此先感谢您的帮助!!

使用字节缓冲区:

boolean concatFiles(StringBuffer sb, File infile, File outfile) {

FileChannel inChan = null, outChan = null;

try {

ByteBuffer buff = ByteBuffer.allocateDirect((int)(infile.length() + sb.length()));
//write the stringBuffer so it goes in the output file first:
buff.put(sb.toString().getBytes());

//create the FileChannels:
inChan = new RandomAccessFile(infile, "r" ).getChannel();
outChan = new RandomAccessFile(outfile, "rw").getChannel();

//read the infile in to the buffer:
inChan.read(buff);

// prep the buffer:
buff.flip();

// write the buffer out to the file via the FileChannel:
outChan.write(buff);
inChan.close();
outChan.close();
} catch...etc

}

使用 trasferTo(或 transferFrom):

boolean concatFiles(StringBuffer sb, File infile, File outfile) {

FileChannel inChan = null, outChan = null;

try {

//write the stringBuffer so it goes in the output file first:
PrintWriter fw = new PrintWriter(outfile);
fw.write(sb.toString());
fw.flush();
fw.close();

// create the channels appropriate for appending:
outChan = new FileOutputStream(outfile, true).getChannel();
inChan = new RandomAccessFile(infile, "r").getChannel();

long startSize = outfile.length();
long inFileSize = infile.length();
long bytesWritten = 0;

//set the position where we should start appending the data:
outChan.position(startSize);
Byte startByte = outChan.position();

while(bytesWritten < length){
bytesWritten += outChan.transferFrom(inChan, startByte, (int) inFileSize);
startByte = bytesWritten + 1;
}

inChan.close();
outChan.close();
} catch ... etc

最佳答案

transferTo() 可以更有效,因为数据复制更少,或者如果可以在内核中完成则没有。如果它不在您的平台上,它仍将使用高度优化的代码。

您确实需要循环,总有一天它会迭代,您的代码将继续工作。

关于java - 使用 FileChannels 在 Java 中连接大文件的方法更有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6065556/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com