Я хочу выяснить, какой из двух методов лучше всего подходит для объединения моих текстовых файлов на Java.Если у кого-то есть понимание того, что он может рассказать о том, что происходит на уровне ядра, которое объясняет разницу между этими методами записи в FileChannel, я был бы очень признателен.
Из того, что я понимаю из документации и других стековПереполнение разговоров, allocateDirect выделяет пространство прямо на диске и в основном избегает использования оперативной памяти.У меня есть опасение, что ByteBuffer, созданный с помощью allocateDirect, может потенциально переполниться или не быть выделенным, если файл имеет большой размер, например, 1 ГБ.На этом этапе разработки нашего программного обеспечения я гарантирую, что размер файла не будет превышать 2 ГБ;но в будущем существует вероятность, что он может достигать 10 или 20 ГБ.
Я заметил, что цикл TransferFrom никогда не проходит цикл более одного раза ... так что, похоже, он успешно записывает весь infile одновременно;но я не проверял его с файлами размером более 60 МБ.Я сделал петлю, потому что в документации указано, что нет гарантии того, сколько будет написано за один раз.Поскольку только TransferFrom может принимать в моей системе параметр int32 в качестве параметра подсчета, я не смогу указать, что за один раз будет передаваться более 2 ГБ ... Опять же, опыт работы с ядром помог бы мне понять.
Заранее спасибо за вашу помощь !!
Использование 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