IO流--文件拷贝和捕获异常

练习:文件拷贝

public class ByteStreamDemo4 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("/Users/jessy/Desktop/offer50/aaa/qqq.txt");
        FileOutputStream fos = new FileOutputStream("/Users/jessy/Desktop/offer50/aaa/copy.txt");

        //拷贝
        //核心思想:边读边写
        int b;
        while ((b = fis.read()) != -1) {
            fos.write(b);
        }

        //先开的最后关闭
        fos.close();
        fis.close();
    }
}
  • FileInputStream读取的问题:如果拷贝的文件过大,那么速度会不会有影响?

会慢,因为FileInputStream一次只读写一个字节。

 

FileInputStream 一次读多个字节

方法名称说明
public int read()一次读一个字节数据
public int read(byte[] buffer)一次读一个字节数组数据
  • 注意:一次读一个字节数组的数据,每次读取会尽可能把数组装满
  • 一般数组长度都是1024的整数倍(1024 * 1024 * 5 = 5MB)
public class ByteStreamDemo5 {
    public static void main(String[] args) throws IOException {
        //abc
        FileInputStream fis = new FileInputStream("/Users/jessy/Desktop/offer50/aaa/qqq.txt");

        //读取数据
        byte[] bytes = new byte[2];
        //一次读取多个字节数据,具体读多少,跟数组的长度有关
        //返回值:本次读取了多少个字节数据
        int len1 = fis.read(bytes);
        //2
        System.out.println(len1);
        String str1 = new String(bytes);
        //ab
        System.out.println(str1);

        int len2 = fis.read(bytes);
        //1
        System.out.println(len2);
        String str2 = new String(bytes);
        //cb
        System.out.println(str2);

        int len3 = fis.read(bytes);
        //-1
        System.out.println(len3);
        String str3 = new String(bytes);
        //cb
        System.out.println(str3);

        fis.close();
    }
}
  • 当最后一次读取数据个数小于数组长度时,最后的数据未被覆盖,导致重新输出,例如上面第二次读写时的cb,但实际上,我们只读了c
  • String str = new String(bytes, 0, len);
public class ByteStreamDemo5 {
    public static void main(String[] args) throws IOException {
        //abc
        FileInputStream fis = new FileInputStream("/Users/jessy/Desktop/offer50/aaa/qqq.txt");

        //读取数据
        byte[] bytes = new byte[2];
        int len1 = fis.read(bytes);
        //2
        System.out.println(len1);
        String str1 = new String(bytes, 0, len1);
        //ab
        System.out.println(str1);

        int len2 = fis.read(bytes);
        //1
        System.out.println(len2);
        String str2 = new String(bytes, 0, len2);
        //c
        System.out.println(str2);

        fis.close();
    }
}

 

练习:文件拷贝(一次读写多个字节)

public class ByteStreamDemo6 {
    public static void main(String[] args) throws IOException {
        long start = System.currentTimeMillis();
        //50,124字节
        FileInputStream fis = new FileInputStream("/Users/jessy/Desktop/offer50/aaa/movie.mp4");
        FileOutputStream fos = new FileOutputStream("/Users/jessy/Desktop/offer50/aaa/copy.mp4");

        int len;
        byte[] bytes = new byte[1024 * 1024 * 5];
        while ((len = fis.read(bytes)) != -1) {
            fos.write(bytes, 0, len);
        }

        fos.close();
        fis.close();

        long end = System.currentTimeMillis();
        //4
        System.out.println(end - start);
        //如果按照之前单个字节拷贝时间是:278
    }
}

 

try…catch异常处理

  • finally里面的代码一定被执行,除非虚拟机停止
  • 基本做法
	try{
		可能出现异常的代码;
	}catch(异常类名 变量名){
		异常的处理代码;
	}finally{
		执行所有资源释放操作;
	}
public class ByteStreamDemo7 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("/Users/jessy/Desktop/offer50/aaa/movie.mp4");
            fos = new FileOutputStream("/Users/jessy/Desktop/offer50/aaa/copy.mp4");

            int len;
            byte[] bytes = new byte[1024 * 1024 * 5];
            while ((len = fis.read(bytes)) != -1) {
                fos.write(bytes, 0, len);
            }

        } catch (IOException e) {
            //e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}
  • 但释放资源的代码过于麻烦,简化!
  • 接口:AutoCloseable
  • 特点:特点情况下,可以自动释放资源
  • JDK7方案:资源用完最终自动释放
    • 注意:只有实现了AutoCloseable 接口的类,才能在小括号中创建对象
	try(创建流对象1;创建流对象2){
		可能出现异常的代码;
	}catch(异常类名 变量名){
		异常的处理代码;
	}
public class ByteStreamDemo8 {
    public static void main(String[] args) {

        try (FileInputStream fis = new FileInputStream("/Users/jessy/Desktop/offer50/aaa/movie.mp4");
             FileOutputStream fos = new FileOutputStream("/Users/jessy/Desktop/offer50/aaa/copy.mp4")) {

            int len;
            byte[] bytes = new byte[1024 * 1024 * 5];
            while ((len = fis.read(bytes)) != -1) {
                fos.write(bytes, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • JKD9方案:资源用完最终自动释放
	创建流对象1;
	创建流对象2;
	try(1;2){
		可能出现异常的代码;
	}catch(异常类名 变量名){
		异常的处理代码;
	}

代码演示:

public class ByteStreamDemo9 {
    public static void main(String[] args) throws FileNotFoundException {
        FileInputStream fis = new FileInputStream("/Users/jessy/Desktop/offer50/aaa/movie.mp4");
        FileOutputStream fos = new FileOutputStream("/Users/jessy/Desktop/offer50/aaa/copy.mp4");

        try (fis; fos) {
            int len;
            byte[] bytes = new byte[1024 * 1024 * 5];
            while ((len = fis.read(bytes)) != -1) {
                fos.write(bytes, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值