我想找出我用来连接Java中的文本文件的两种方法更好。如果某人有一些洞察力,他们可以分享内核级别的内容,这些内容解释了这些写入FileChannel的方法之间的区别,我将非常感激。
根据我从文档和其他Stack Overflow对话中的理解,allocateDirect在驱动器上分配空间,并且主要避免使用RAM。我担心如果File infile很大,比如1GB,使用allocateDirect创建的ByteBuffer可能会溢出或不被分配。在我们的软件开发中,我保证文件不会超过2 GB;但未来有潜力可能会达到10或20GB。
我观察到transferFrom循环不会多次通过循环...因此它似乎成功地立即写入整个infile;但我没有用大于60MB的文件测试它。我虽然循环,因为文档规定不能保证一次写入多少。使用transferFrom只能在我的系统上接受int32作为其count参数,我将无法一次指定超过2GB的内容...再次,内核专业知识将帮助我理解。
先谢谢你的帮助!!
使用ByteBuffer :
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
答案 0 :(得分:3)
transferTo()可以更有效率,因为数据复制较少,如果可以在内核中完成,则无效。如果它不在您的平台上,它仍将使用高度调整的代码。
你确实需要循环,有一天它将迭代,你的代码将继续工作。