java文件拷贝的一点思考
“talk is cheap,show me the code"。鉴于此,直接上代码
1 /** 2 * @Description: 将源文件复制到目标文件中 3 * @param oldFile 源文件 4 * @param newfile 目标文件 5 * @author jiangwang 6 * @date Apr 27, 2017 7 */ 8 public static void copyFile(File oldFile, File newfile)throws IOException { 9 FileInputStream in = new FileInputStream(oldFile); 10 FileOutputStream out = new FileOutputStream(newfile); 11 //byte[] buffer = new byte[(int)oldFile.length()];① 12 byte[] buffer = new byte[1024];② 13 int n = 0; 14 while ((n=in.read(buffer)) != -1) { 15 out.write(buffer,0,n);③ 16 // out.write(buffer);④ 17 out.flush(); 18 } 19 }
上面这段java代码,可以实现文件复制功能。(代码已被精简,包括异常处理、文件流关闭等)
这段代码最初是②④组合。出现文件部分内容被重复拷贝了,而且是文件的中间内容被重复拷贝了。
举例,文件中有:abcd,复制了之后可能变成abcdbc。
由于发现了这个问题。改成了①④组合。解决了这个问题。
鉴于“知其所以然”的精神,做了一点小研究。
result:
②④组合重复拷贝原因:
假设一文件长度为2024字节,第一次读取了1024字节,存入buffer,然后out.write(buffer),没问题。第二次读取了1000,由于buffer长度为1024字节,所以前1000个字节是新读取的,后24个字节是上一次读取的,然后out.write(buffer),肯定会出现有内容被重复读取了。
①④组合:
这个buffer的长度为文件内容长度,所有一次读完所有内容,然后out.write(buffer),可以完成拷贝。
思考出的最优解:
①④组合并不完美,如果文件较大,服务器内存存在风险,且效率较低。
完美的组合是②③。这样既可以解决大文件内存压力问题,也可以完成复制功能。原因是无论读取多少次文件,最后一次复制指定长度的字节,不会去重复复制上一次剩下的尾巴。