为什么我的输出文件的大小小于原始文件?
Why my output file's size is less than origin file?
我想通过文件通道高效地传输大文件,所以我使用java.io.RandomAccessFile
和java.nio.channels.FileChannel
来传输文件。
而且我得到的输出文件不对,小于原始源文件。这是代码:
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();
}
}
}
对了,我的输入文件是一个mkv视频文件,大小是2937236651字节。当我用 java.io.BufferedInputStream
和 java.io.BufferedOutputStream
复制它时,没有问题。
好吧,对于您的新更新,文件大于 2GB,有一个限制 OS 来为此类操作创建缓冲区,在这种情况下,您需要更新您的应用程序以使其适用于文件大于 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");
}
}
你的复制步骤有误。 transferTo()
未指定在一次调用中传输整个输入。这就是它 returns 的原因。你必须循环,增加偏移量并减少长度,直到没有任何东西可以传输。
我想通过文件通道高效地传输大文件,所以我使用java.io.RandomAccessFile
和java.nio.channels.FileChannel
来传输文件。
而且我得到的输出文件不对,小于原始源文件。这是代码:
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();
}
}
}
对了,我的输入文件是一个mkv视频文件,大小是2937236651字节。当我用 java.io.BufferedInputStream
和 java.io.BufferedOutputStream
复制它时,没有问题。
好吧,对于您的新更新,文件大于 2GB,有一个限制 OS 来为此类操作创建缓冲区,在这种情况下,您需要更新您的应用程序以使其适用于文件大于 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");
}
}
你的复制步骤有误。 transferTo()
未指定在一次调用中传输整个输入。这就是它 returns 的原因。你必须循环,增加偏移量并减少长度,直到没有任何东西可以传输。