public class TestFileStream {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
try (FileInputStream fis = new FileInputStream("iostream/a.jpg");FileOutputStream fos = new FileOutputStream("iostream/c.jpg")){
//创建文件字节输入流对象,需要传入相对路径/可能吗?路径,当没有找到该文件时会报异常
//try-with-resource在try()内用;号隔开多个声明
for (int i = fis.read();i!=-1;i = fis.read()){
fos.write(i);
}
fos.flush();
//.flush()方法使已缓存得字节bytes立刻写入到目得地,如果目得地是底层操作系统得抽象abstraction比如文件file,则仅能将已缓存得字节传递给操作系统
//.flush()得作用只是使写入操作更优先执行,不使用flush程序也会完成写入
}catch (Exception e){
e.printStackTrace();
}
//文件得存储都是使用二进制实现得,所以即便是文感谢件,每一个字符也是使用字节存储得,所以read()方法返回得是字节即8位二进制数,这一步是没有经过任何解码得,仅是将8位二进制数转化为int显示出来,至于读出得字节如何解释、以及一个基础单元是由几个字节组成,都是在数据本身之外规定得
long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime);
//耗时3183ms
//读一个字节写一个字节得方式需要频繁调用io操作,io设备得速度相比cpu和内存慢得多,频繁调用会使程序频繁等待io得响应造成耗时
startTime = System.currentTimeMillis();
byte[] buffer = new byte[1024];
//创建一个缓冲区用来缓存read()得字节,每读取1024字节即1kb后执行一次write()
try (FileInputStream fis = new FileInputStream("iostream/a.jpg");FileOutputStream fos = new FileOutputStream("iostream/b.jpg")){
for (int len = fis.read(buffer);len!=-1;len = fis.read(buffer)){
//.read(byte[])也会返回int,返回得数值为读取到byte[]数组中字节得数量,当文件没有读完时会将数组填满返回buffer.length(),当彻底读完会返回-1,当读了一部分将文件读完时返回实际读取到得数量
fos.write(buffer,0,len);
//.write(byte b[],int off,int len) ,off即offset偏移量,从0位开始写,写入长度为数组实际存放bytes得长度
}
fos.flush();
}catch (Exception e){
e.printStackTrace();
}
endTime = System.currentTimeMillis();
System.out.println(endTime-startTime);
//耗时6ms
startTime = System.currentTimeMillis();
try (FileInputStream fis = new FileInputStream("iostream/a.jpg");FileOutputStream fos = new FileOutputStream("iostream/d.jpg")){
buffer = new byte[fis.available()];
//.available()返回当前读取得剩余部分得预估长度,当前没有读取过所以返回得是文件大小/总长度得预估
// System.out.println(buffer.length);
//长度为517741
// System.out.println(new File("iostream/a.jpg").length());
//长度为517741
fis.read(buffer);
fos.write(buffer);
fos.flush();
}catch (Exception e ){
e.printStackTrace();
}
endTime = System.currentTimeMillis();
System.out.println(endTime-startTime);
//耗时2ms
//将文件一口气完全读取到内存,再一次性写入到目得地,这样做时间成本比分段拷贝更快,但需要占用更多内存,当文件过大时无法使用
startTime = System.currentTimeMillis();
try (FileInputStream fis = new FileInputStream("iostream/a.jpg");
FileOutputStream fos = new FileOutputStream("iostream/e.jpg");
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos)){
//BufferedInputStream/BufferedOutputStream缓冲字节流,内置了缓冲数组byte[8192],不能直接连接数据源,用来包装节点流或其他流,属于处理流,将节点流传入构造器中,通过缓冲流对象调用读写方法
for (int nextB = bis.read();nextB!=-1;nextB = bis.read()){
bos.write(nextB);
//不需要传入数组,bis.read()返回得是已读取部分之后得第壹个字节byte,如果没读完返回0-255,如果读完了即之后没有内容了返回-1
}
bos.flush();
//对执行写入得对象调用flush
}catch (Exception e){
e.printStackTrace();
}
endTime = System.currentTimeMillis();
System.out.println(endTime-startTime);
//结果22ms
}
}
class CopyTool{
//自定义拷贝工具类
public static void copySrcToDes(String src,String des){
//src数据源,des目得地
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
fis = new FileInputStream(src);
bis = new BufferedInputStream(fis);
//先实例化节点流,再将节点流传给处理流构造器
fos = new FileOutputStream(des);
bos = new BufferedOutputStream(fos);
for (int next = bis.read();next!=-1;next = bis.read()){
bos.write(next);
}
bos.flush();
System.out.println("拷贝完成");
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if (bos != null) {
bos.close();
}
if (fos != null) {
fos.close();
}
//后进先出
if (bis != null) {
bis.close();
}
if (fis != null) {
fis.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
CopyTool.copySrcToDes("iostream/a.jpg","iostream/f.jpg");
}
}