我对使用流复制文件的方法有疑问:
void *
复制例如图像,.txt文件或有时视频文件时出现问题,错误“文件大小不匹配”。发生。当我比较源文件和目标文件大小时,大小确实不匹配,但打开后的图像似乎也是完整的,视频也是如此。可见的问题是文本文件 - 复制并丢失几个字节后,没有任何内容丢失,但在文件的末尾有几行标有“NUL”的某种标记 - 使用Notepad ++查看这些内容。
我尝试使用Files中的copy()方法,它正常工作,但我无法找出为什么我的方法丢失了字节。
非常感谢您的帮助,我无法在任何地方找到解决方案。
答案 0 :(得分:0)
读取循环是问题:
while(is.read(buffer) > 0) {
read += buffer.length;
os.write(buffer);
first = Math.round(read / src.length() * 100);
if(first != second) {
System.out.println(first + " % copied.");
}
second = Math.round(read / src.length() * 100);
}
is.read(buffer)
返回读取的字节数。首先,您必须检查它是否大于或等于零,因为read
的契约允许它在缓冲区大小为零时读取0个字节。但除此之外 - 你需要保持这个值,因为你必须只写你读的字节数。
通常,文件的大小不是4096的倍数。因此,最后一次读取将读取少于4096个字节。 read
合同实际上说,如果当时可用的字节数减少,它甚至可以读取少于4096个。
因此,如果您没有准确写出已读取的内容,则您编写的缓冲区的一部分将包含上一次读取的值,如果文件小于4096字节,则为零。
所以纠正它:
int numRead;
while( (numRead = is.read(buffer)) >= 0) {
read += numRead;
os.write(buffer,0,numRead);
first = Math.round(read / src.length() * 100);
if(first != second) {
System.out.println(first + " % copied.");
}
second = Math.round(read / src.length() * 100);
}
但实际上,建议每当您的副本涉及至少一个文件时使用Files
类,并避免java.io.File
支持Path
,{{1}中的操作可用}和Paths
。