37.I/O流

1.概述

 2.分类

 3.字节流

        /**
         * 创建字节输出流对象,下面的的语句一共做了3件事情:
         * A:调用系统功能,创建了文件
         * B:创建了字节输出流对象
         * C:让字节输出流对象指向创建好的文件
         */
        FileOutputStream outputStream = new FileOutputStream("D:\\abc\\a.txt");
        outputStream.write(97);//将指定的字节写入此文件输出流。
        outputStream.close();//void close​() 关闭此文件输出流并释放与此流相关联的任何系统资源。 

字节流写数据的3种方式

 

FileOutputStream outputStream = new FileOutputStream("D:\\abc\\a.txt");
        outputStream.write(97);//将指定的字节写入此文件输出流。
        byte []b={97,98,99,100,101};
        //getBytes​() 使用平台的默认字符集将该 String编码为一系列字节,将结果存储到新的字节数组中。
        byte[] bb="qwer".getBytes();//{113,119,101,114}
        outputStream.write(b);
        outputStream.write(b,1,3);
        outputStream.close();//void close​() 关闭此文件输出流并释放与此流相关联的任何系统资源。

补充:换行和追加写入

 FileOutputStream outputStream = new FileOutputStream("D:\\abc\\a.txt",true);
byte[] bb="qwer".getBytes();//{113,119,101,114}
for (int i=0;i<10;i++){
            outputStream.write(bb);
            outputStream.write("\r\n".getBytes());
        }

异常处理

        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream("D:\\abc\\a.txt",true);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                if (outputStream!=null){
                    outputStream.close();//无论什么时候都要关闭资源
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

字节流读数据

一次读取一个字节:

        FileInputStream inputStream =null;
        inputStream = new FileInputStream("D:\\abc\\a.txt");
            int  b=inputStream.read();//返回数据的下一个字节,如果达到文件的末尾,返回 -1 。
            System.out.println(b);//97
            System.out.print((char)b);//a
            //字节流读数据标准代码:
            int by;
            while ((by=inputStream.read())!=-1){
                System.out.print((char)by);
            }    

一次读取(一个字节数组长度)的数据:

 FileInputStream inputStream = new FileInputStream("D:\\abc\\a.txt");
        byte bb[]=new byte[4];
        int len;//每次实际读取的字节长度
        /**
         * 注意!!!,例如我们的要读取的文档内容是:abcdefghij,一共有10个字节,那么:
         * 第一次读取4个字节:abcd,此时bb[]数组被填充为:{a,b,c,d}
         * 第二次读取4个字节:efgh,此时bb[]数组被填充为:{e,f,g,h}
         * 第三次读取2个字节:ij  ,此时bb[]数组被填充为:{ij,g,h}....
         * 总结:也就是说最后一次读取如果内容长度小于定义的数组长度,那么就会出问题:最后一次读取的内容包含部分上次读取的内容!!!
         */
        while ((len=inputStream.read(bb))!=-1){
            System.out.print(new String(bb));//abcdefghijgh
        }
        /**
         * 所以我们在使用byte[]创建字符串的时候只截取实际读取长度的内容转换成字符串就可以避免发生上面的错误了:
         * String​(byte[] bytes, int offset, int length) 通过使用平台的默认字符集解码指定的字节子阵列来构造新的 String 。  
         */
        byte b[]=new byte[1024];//一般都是1024或者1024倍数
        int lengh;//每次实际读取的字节长度
        while ((lengh=inputStream.read(b))!=-1){
            System.out.print(new String(b,0,lengh));
        }

案例:复制图片

FileOutputStream outputStream = new FileOutputStream("D:\\abc\\火灾.png");
FileInputStream inputStream = new FileInputStream("D:\\abc\\火.png");
 byte b[]=new byte[1024];//一般都是1024或者1024倍数
        int lengh;//每次实际读取的字节长度
        while ((lengh=inputStream.read(b))!=-1){
            outputStream.write(b,0,lengh);//注意,这里读取多少写出多少
        }

 字节缓冲流

 File file = new File("D:\\abc\\a.txt");
        FileInputStream inputStream = new FileInputStream(file);
        FileOutputStream outputStream = new FileOutputStream("D:\\abc\\b.txt");
        BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
        byte[] bytes = new byte[1024];
        int lengh;
        while ((lengh = bufferedInputStream.read(bytes)) != -1) {
            System.out.println(new String(bytes, 0, lengh));
            bufferedOutputStream.write(bytes, 0, lengh);
        }
        bufferedOutputStream.write("123456".getBytes());
        bufferedInputStream.close();
        bufferedOutputStream.flush();//注意!!!这里别忘了flush,要不然可能会导致缓冲区里面的内容没有完全写入
        inputStream.close();
        outputStream.close();

 字节缓冲流复制视频的四种方式

import java.io.*;
public class MoveMoves {
    public static String basePath = "D:\\abc\\两个警察笑完整版.mp4";
    public static String targetDir = "D:\\abc\\a\\";
    public static void main(String[] args) throws IOException {
        //记录开始时间
        long beginTime = System.currentTimeMillis();
        copy1();
//        copy2();
//        copy3();
//        copy4();
        //记录结束时间
        long endTime = System.currentTimeMillis();
        System.out.println("共计耗时:" + (endTime - beginTime) + "毫秒");
    }

    /**
     * 封装四个方法,使用以下四种方式复制大小为29810KB的视频:
     * 1.基本字节流,一次读写一个字节              共计耗时:167293毫秒
     * 2.基本字节流,一次读取一个字节数组          共计耗时:416毫秒
     * 3.字节缓冲流,一次读取一个字节              共计耗时:2787毫秒
     * 4.字节缓冲流,一次读取一个字节数组          共计耗时:130毫秒
     */
    public static void copy1() throws IOException {//1.基本字节流,一次读写一个字节
        FileInputStream fileInputStream = new FileInputStream(basePath);
        FileOutputStream fileOutputStream = new FileOutputStream(targetDir + "1.mp4");
        int by;
        while ((by = fileInputStream.read()) != -1) {
            fileOutputStream.write(by);
        }
        fileOutputStream.close();
        fileInputStream.close();
    }

    public static void copy2() throws IOException {//2.基本字节流,一次读取一个字节数组
        FileInputStream fileInputStream = new FileInputStream(basePath);
        FileOutputStream fileOutputStream = new FileOutputStream(targetDir + "2.mp4");
        byte[] bytes = new byte[1024];
        int length;
        while ((length = fileInputStream.read(bytes)) != -1) {
            fileOutputStream.write(bytes, 0, length);
        }
        fileOutputStream.close();
        fileInputStream.close();
    }

    public static void copy3() throws IOException {//3.字符缓冲流,一次读取一个字节
        FileInputStream fileInputStream = new FileInputStream(basePath);
        FileOutputStream fileOutputStream = new FileOutputStream(targetDir + "3.mp4");
        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        int bytes;
        while ((bytes = bufferedInputStream.read()) != -1) {
            bufferedOutputStream.write(bytes);
        }
        bufferedOutputStream.flush();
        bufferedOutputStream.close();
        bufferedInputStream.close();
        fileOutputStream.close();
        fileInputStream.close();
    }

    public static void copy4() throws IOException {//4.字符缓冲流,一次读取一个字节数组
        FileInputStream fileInputStream = new FileInputStream(basePath);
        FileOutputStream fileOutputStream = new FileOutputStream(targetDir + "4.mp4");
        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        byte[] bytes = new byte[1024];
        int length;
        while ((length = bufferedInputStream.read(bytes)) != -1) {
            bufferedOutputStream.write(bytes, 0, length);
        }
        bufferedOutputStream.flush();
        bufferedOutputStream.close();
        bufferedInputStream.close();
        fileOutputStream.close();
        fileInputStream.close();
    }

}

字符流

为什么出现字符流

        /**
         * 一个汉字储存:
         * 如果是GBK编码:占用2个字节
         * 如果是UTF-8编码:占用3个字节
         */
        File file = new File("D:\\abc\\a.txt");//文本内容为:abcdefghi中国
        FileInputStream fileInputStream = new FileInputStream(file);
        int b;
        while ((b=fileInputStream.read())!=-1){
            System.out.print((char)b);//abcdefghiÖйú
        }
        String s2="中国";
        byte[] bytesUTF8 = s2.getBytes("UTF-8");
        byte[] bytesGBK = s2.getBytes("GBK");
        System.out.println(Arrays.toString(bytesUTF8));//[-28, -72, -83, -27, -101, -67]
        System.out.println(Arrays.toString(bytesGBK));//[-42, -48, -71, -6]
//        上面之所以在输出汉字的时候乱码,是因为我们每读取一个字节例如是"-28",我们将她转换成字符的时候很明显她只是"三分之一"个字符,所以就会乱码

编码表

 字符集

 

 

 

 

 

 字符串中的编码解码

 字符流概述

 字符流写数据的5种方法

        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\abc\\c.txt"));
        int a=97;
        char c[]={'a','b','中','国','人'};
        outputStreamWriter.write(a);
        outputStreamWriter.write(c);
        outputStreamWriter.write(c,1,3);
        outputStreamWriter.write("123456");
        outputStreamWriter.write("123456",2,3);
        outputStreamWriter.flush();

字符流读数据的两种方式

        InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("D:\\abc\\a.txt"), "GBK");
        int by;
        char[] chars = new char[1024];
        while ((by=inputStreamReader.read())!=-1){
            System.out.print((char)by);//哈哈哈,好消息
        }
        int length;
        while ((length=inputStreamReader.read(chars))!=-1){
            System.out.print(new String(chars,0,length));//哈哈哈,好消息
        }

字符流复制文件

        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\abc\\b\\ReaderDemo.java"));
        InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("D:\\abc\\ReaderDemo.java"));
        char[] chars = new char[1024];
        int length;
        while ((length = inputStreamReader.read(chars)) != -1) {
            outputStreamWriter.write(chars, 0, length);
        }
        outputStreamWriter.flush();
        outputStreamWriter.close();
        inputStreamReader.close();

字符流复制文件升级版

        FileReader fileReader = new FileReader("D:\\abc\\ReaderDemo.java");
        FileWriter fileWriter = new FileWriter("D:\\abc\\a\\ReaderDemo.java");
        int ch;
        while ((ch=fileReader.read())!=-1){
            fileWriter.write(ch);
        }
        int len;
        char[] chars1 = new char[1024];

        while ((len=fileReader.read(chars1))!=-1){
            fileWriter.write(chars1,0,len);
        }
        fileWriter.close();
        fileReader.close();

字符缓冲流

        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\abc\\aaaa.txt"));
        bufferedWriter.write("123456789");
        bufferedWriter.close();

        BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\abc\\aaaa.txt"));
        int c;
        while ((c=bufferedReader.read())!=-1){
            System.out.println((char)c);
        }
        int l;
        char[] chars2 = new char[1024];
        while ((l=bufferedReader.read(chars2))!=-1){
            System.out.println(new String(chars2,0,l));
        }
        bufferedReader.close();

 字符缓冲流特有方法

BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\abc\\a\\aa.txt"));
String s="aaa";
        for (int i=0;i<10;i++){
            bufferedWriter.write(s);
       bufferWriter.flush(); bufferedWriter.newLine(); } bufferedWriter.close();
BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\abc\\a\\aa.txt"));
 String read;
        while ((read=bufferedReader.readLine())!=null){
            System.out.println(read);
        }
  bufferedReader.close();

IO小结

 

 

 复制多级文件夹

public class Fuzhi2 {
    public static void main(String[] args) throws IOException {
//        把D:\abc下面的a文件夹复制到D:\abc\def下面,也就是def下面新增一个a文件夹
        File file = new File("D:\\abc\\a");//要复制的文件夹路径
        String name = file.getName();
        File targetDir = new File("D:\\abc\\def");//要将文件夹复制到哪个路径之下
        File newRootDir = new File(targetDir, file.getName());
        if (!newRootDir.exists()) newRootDir.mkdirs();
        copyFiles(file, newRootDir);
    }


    private static void copyFiles(File file, File targetDir) throws IOException {
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                File newChildDir = new File(targetDir, f.getName());
                if (!newChildDir.exists()) {
                    newChildDir.mkdir();
                    copyFiles(new File(file, f.getName()), newChildDir);
                }
            } else {
                BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(f));
                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(new File(targetDir, f.getName())));
                int length;
                byte[] bytes = new byte[1024];
                while ((length = bufferedInputStream.read(bytes)) != -1) {
                    bufferedOutputStream.write(bytes, 0, length);
                }
                bufferedOutputStream.flush();
                bufferedOutputStream.close();
                bufferedInputStream.close();
            }
        }

    }
}

 IO流异常处理

    public static void main(String[] args) {
        method3();
        System.out.println("程序继续执行了");
    }

    //1.抛出异常(实质上并没有处理)
    private static void method1() throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\abc\\a.txt"));
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\abc\\b\\a.txt"));
        int length;
        char[] chars = new char[1024];
        while ((length = bufferedReader.read(chars)) != -1) {
            bufferedWriter.write(chars, 0, length);
            bufferedWriter.flush();
        }
        bufferedWriter.close();
        bufferedReader.close();
    }

    //2.标准异常处理流程
    private static void method2() {
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
            bufferedReader = new BufferedReader(new FileReader("D:\\abc\\a.txt"));
            bufferedWriter = new BufferedWriter(new FileWriter("D:\\abc\\b\\a.txt"));
            int length;
            char[] chars = new char[1024];
            while ((length = bufferedReader.read(chars)) != -1) {
                bufferedWriter.write(chars, 0, length);
                bufferedWriter.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bufferedWriter!=null){
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader!=null){
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //3.JDK7以后的改进方案(自动释放资源)
    private static void method3() {
        try (BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\abc\\a.txt"));
             BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\abc\\b\\a.txt"));) {
            int length;
            char[] chars = new char[1024];
            while ((length = bufferedReader.read(chars)) != -1) {
                bufferedWriter.write(chars, 0, length);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //4.JDK9以后:将流对象定义在try外面(自动释放资源)
    private static void method4()  throws IOException{//这里还是要抛出异常,相比JDK7的方法,还是不如JDK7
        BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\abc\\a.txt"));
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\abc\\b\\a.txt"));
        try (bufferedReader;bufferedWriter) {
            int length;
            char[] chars = new char[1024];
            while ((length = bufferedReader.read(chars)) != -1) {
                bufferedWriter.write(chars, 0, length);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //5.JDK7以后的改进方案(自动释放资源)适用于所有流
    private static void method5() {
        try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("D:\\abc\\a.txt"));
             BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("D:\\abc\\b\\a.txt"));) {
            int length;
            byte[] bytes = new byte[1024];
            while ((length = bufferedInputStream.read(bytes)) != -1) {
                bufferedOutputStream.write(bytes, 0, length);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
posted @ 2020-06-21 23:35  指尖下的世界  阅读(186)  评论(0编辑  收藏  举报
/* 看板娘 */ /*炸泡*/
/* 鼠标点击求赞文字特效 */