import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* 注意事项:
* int java.io.FileInputStream.read(byte[] b) throws IOException
* 方法的官方文档描述:
* Reads up to b.length bytes of data from this input stream into an array of bytes.
* This method blocks until some input is available.
* 即可以这么理解:
* FileInputStream会不断地读取字节数据到字节数组b中.
* 只要读了一次,那么我们就相应地执行一次写的操作:
* fileOutputStream.write(temp,0,len);
* 什么情况下这个读的过程会终止呢?
* 当已经读取到数据末尾的时候,有个标识符-1;表示已经到了末尾.
*
* 有种不太恰当的理解:
* FileInputStream会一次次地读取字节数据到字节数组b中.
* 每读一次后,就会稍微暂停一下,然后执行
* fileOutputStream.write(temp,0,len);
* 进行数据写的操作.
*
* 其实如下理解更合适一些:
* FileInputStream是在不断地读数据(而不要想象成带有暂停性质的一次次地读取).
* 只是它每读一次的数据必然不超过b.length的大小,但有可能是不一样的长度,
* 比如:在极多数情况下,最后一次的时候读取的字节数会小于b.length大小.
* 每采用read()方法读一次呢,读到的数据就会存到字节数组b中,并且该方法
* 还返回了这次读取的字节的多少(len).
* 于是我们对字节数组b中从o到len的数据进行写操作:
* fileOutputStream.write(temp,0,len);
*
* 现在就明白了为什么使用:
* fileOutputStream.write(temp);
* 是不准确的,很可能导致复制后的照片比原始照片大.
* 因为fileOutputStream.write(temp);方法每次都是
* 写了b字节数组大小的数据,而不是已经b中实际有多少
* 数据.
* 这样的操作在前几次是没有什么问题的,因为每次装的
* 都是b字节数组大小的数据,但是最后一次往往是装不满
* b的.所以每次应该根据b中的实际数据到底有多少来进行
* 操作即采用fileOutputStream.write(temp,0,len);
* 可以兼顾到每一次.
*/
public class CopyPhoto {
public static void main(String[] args) {
CopyPhoto copyPhoto = new CopyPhoto();
copyPhoto.copy();
}
private void copy() {
try {
FileInputStream fileInputStream=new FileInputStream("D:\\c.jpg");
FileOutputStream fileOutputStream=new FileOutputStream("D:\\new.jpg");
int len=0;
byte temp []=new byte[1024*8];;
while((len=fileInputStream.read(temp))!=-1){
System.out.println("len="+len);
//It is right
fileOutputStream.write(temp,0,len);
//It is wrong
//fileOutputStream.write(temp);
}
fileOutputStream.close();
fileInputStream.close();
} catch (Exception e) {
}
}
}