I want to transfer big file by file channel efficiently, so I use java.io.RandomAccessFile
and java.nio.channels.FileChannel
to transfer file.
And I get the output file is not right, which is less than the origin source file. Here is the code:
public static void transferByRandomAccess(String inputFile, String outputFile) throws IOException {
RandomAccessFile inputRandomAccessFile = null;
RandomAccessFile outputRandomAccessFile = null;
try {
inputRandomAccessFile = new RandomAccessFile(inputFile, "r");
FileChannel inputFileChannel = inputRandomAccessFile.getChannel();
outputRandomAccessFile = new RandomAccessFile(outputFile, "rw");
FileChannel outFileChannel = outputRandomAccessFile.getChannel();
inputFileChannel.transferTo(0, inputFileChannel.size(), outFileChannel);
inputFileChannel.force(true);
outFileChannel.force(true);
} finally {
if (outputRandomAccessFile != null) {
outputRandomAccessFile.close();
}
if (inputRandomAccessFile != null) {
inputRandomAccessFile.close();
}
}
}
By the way, my input file is a mkv video file, whose size is 2937236651 byte. And while I copy it with java.io.BufferedInputStream
and java.io.BufferedOutputStream
, there is no problem.
Well, for your new update, the file is larger than 2GB, there is a limit of OS to make buffer for such operation, in this case you need to update your application to make it works for file larger than 2GB
public class Test {
public static void main(String[] args) throws Exception {
RandomAccessFile inputRandomAccessFile = null;
RandomAccessFile outputRandomAccessFile = null;
try {
inputRandomAccessFile = new RandomAccessFile("G:\\file1.zip", "r");
FileChannel inputFileChannel = inputRandomAccessFile.getChannel();
outputRandomAccessFile = new RandomAccessFile("G:\\file2.zip", "rw");
FileChannel outFileChannel = outputRandomAccessFile.getChannel();
long readFileSize = inputFileChannel.size();
long transferredSize = 0;
do {
long count = inputFileChannel.transferTo(transferredSize, inputFileChannel.size(), outFileChannel);
transferredSize += count;
} while (transferredSize < readFileSize);
inputFileChannel.force(true);
outFileChannel.force(true);
} finally {
if (outputRandomAccessFile != null) {
outputRandomAccessFile.close();
}
if (inputRandomAccessFile != null) {
inputRandomAccessFile.close();
}
}
System.out.println("DONE");
}
}