为何使用FileInputStream.read()与FileOutputStream.write()复制文件失败?
问题分析:为何文件复制代码未达到预期效果?
哦,这个坑好多新手都会踩!你的代码核心问题出在循环里重复调用了FileInputStream.read()方法,直接导致你丢失了一半的字节,还可能写入无效数据,最终复制出的文件自然和原文件完全不同。
具体问题拆解
咱们一步步捋你的循环逻辑:
while (original.read() != -1) { copy.write(original.read()); }
- 第一次调用
original.read()是在while的条件判断里:这时候已经从输入流读取了一个字节(返回值是该字节的int表示,范围0-255;如果流读完了,返回-1),但你没把这个值存下来,只用来判断是否继续循环。 - 紧接着在循环体里又调用了一次
original.read():这时候读取的是下一个字节,然后把这个字节写入输出流。
换句话说,你每一轮循环都跳过了条件判断时读到的那个字节,只写入了“第2、4、6……”个字节。更糟的是,如果原文件字节数是奇数,最后一次条件判断的read()返回-1,循环不会执行;但如果是偶数,最后一次循环体里的read()会返回-1,你还会把这个无效值写入输出流,多出来的字节也会破坏文件结构。
修正后的代码
解决方法特别简单:把每次读到的字节存到一个变量里,用同一个变量做判断和写入操作,同时别忘了关闭流(这是IO操作的良好习惯):
import java.io.*; class CopyFile { public static void main(String[] args) throws IOException { FileInputStream original = new FileInputStream(args[0]); FileOutputStream copy = new FileOutputStream(args[1]); int byteRead; // 一次读取字节并存入变量,复用这个值做判断和写入 while ((byteRead = original.read()) != -1) { copy.write(byteRead); } // 关闭流,释放系统资源 original.close(); copy.close(); } }
额外优化建议
如果处理大文件,单字节读写效率很低,建议用缓冲流批量读写,能大幅提升速度,还可以用try-with-resources语法自动关闭流,避免遗漏:
import java.io.*; class CopyFile { public static void main(String[] args) throws IOException { // try-with-resources会在代码块结束后自动关闭流 try (BufferedInputStream original = new BufferedInputStream(new FileInputStream(args[0])); BufferedOutputStream copy = new BufferedOutputStream(new FileOutputStream(args[1]))) { int byteRead; while ((byteRead = original.read()) != -1) { copy.write(byteRead); } } } }
内容的提问来源于stack exchange,提问作者Ryan H.
相关产品推荐
相关产品推荐

