一篇文章搞懂流

一.File类

1.File类的理解

①File类的一个对象,代表着一个文件或一个文件目录(即文件夹)
②File类声明在java.io包下
③File类中涉及关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,并未涉及写入或读取文件内容的操作,如果需要读取或写入文件内容,必须使用IO流来完成
④后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的“终点”
⑤这里的相对路径是相对当前module的路径(如果是在单元测试里面调用)或者是当前工程下的路径(如果是在Main里面调用)

2.创建File类的实例

		File file = new File(String filePath);
        File file = new File(String parentPath,String childPath);
        File file = new File(String parentFile,String childPath);

三种方法都很常用

3.File的常用方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二.Java的IO

1.JavaIO简介

IO是Input和Output的缩写,IO技术是非常实用的技术,用于处理设备之间的数据传输。比如读写文件,网络通信等。

2.流的分类

分类标准 具体分类
操作数据单位 字节流(8bit)和字符流(16bit)
数据流的流向 输入流和输出流
流的角色 节点流和处理流

在这里插入图片描述
总体分类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
特别重要的是
在这里插入图片描述

3.FileReader的使用

注意,在finally的时候,有可能fr是null的,为避免出现空指针异常,所以加了if语句进行一个判断。

使用read的空参方法
		FileReader fr = null;
        try {
    
    
            //1.创建File类的实例
            File file = new File("hello.txt");

            //2.提供具体的流
            fr = new FileReader(file);

            //3.读取数据。返回读入的一个字符,如果达到文件末尾,返回-1
//        int data = fr.read();
//        while (data != -1){
    
    
//            System.out.println((char)data);
//            data = fr.read();
//        }

            //语法上还可以进行一个优化
            int data;
            while ((data = fr.read()) != -1){
    
    
                System.out.println((char)data);
                /*
                h
                e
                l
                l
                o
                w
                o
                r
                l
                d
                 */
            }
        }catch (IOException e){
    
    
            e.printStackTrace();
        }finally {
    
    
            try {
    
    
                if(fr != null) {
    
    
                    //4.流的关闭
                    fr.close();
                }
            }catch (IOException e){
    
    
                e.printStackTrace();
            }

        }


使用read的带参方法
		FileReader fr = null;
        try {
    
    
            //1.创建File类的实例
            File file = new File("hello.txt");

            //2.提供具体的流
            fr = new FileReader(file);

            //3.读取数据。返回读入的一个字符,如果达到文件末尾,返回-1
            char[] cbuf = new char[5];
            //fr.read(cbuf);//这个方法是返回每次读入cbuf数组中的字符的个数,如果达到文件末尾,返回-1
            //方式一
            int len;
            while ( (len = fr.read(cbuf))  != -1){
    
    
                  //方式一
//                for (int i = 0;i < len;i++){
    
    
//                    System.out.print(cbuf[i]);//现在还是一个“覆盖式”的
//                    //helloworld123
//                }

                  //方式二
                  String string = new String(cbuf,0,len);
                  System.out.println(string);
                  /*
                    hello
                    world
                    123
                   */
            }
        }catch (IOException e){
    
    
            e.printStackTrace();
        }finally {
    
    
            try {
    
    
                if(fr != null) {
    
    
                    //4.流的关闭
                    fr.close();
                }
            }catch (IOException e){
    
    
                e.printStackTrace();
            }

        }

4.FileWriter的使用

如果是FileWriter(file,false)/FileWriter(file),则表示对原有文件的覆盖
如果是FileWriter(file,true),则不会对原有文件覆盖,而是在原有文件基础上追加内容

		FileWriter fw = null;
        try {
    
    
            //1.创建File类的实例
            File file = new File("hello.txt");

            //2.提供FileWriter的对象,用于数据的到处
            fw = new FileWriter(file,false);//false表示不追加,即对原有文件的覆盖

            //3.具体的写出
            fw.write("I have a dream\n",);
            fw.write("You have a dream");

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

        }

5.读和写结合(FileReader和FileWriter)

不能使用字符流处理字节文件
即对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt…),使用字节流处理

		//1.定义两个流
        FileReader fr = null;
        FileWriter fw = null;
        try {
    
    
            //2.创建文件
            File srcFile = new File("hello.txt");
            File desFile = new File("hello2.txt");

            //3.创建流
            fr = new FileReader(srcFile);
            fw = new FileWriter(desFile,true);

            //4.读取数据
            char[] srcs = new char[5];
            int len;
            while ((len = fr.read(srcs)) != -1){
    
    
                System.out.println(new String(srcs));
                System.out.println(len);
                fw.write(srcs,0,len);
            }
        }catch (IOException e){
    
    
            e.printStackTrace();
        }finally {
    
    
            if(fr != null){
    
    
                try {
    
    
                    fr.close();
                }catch (IOException e){
    
    
                    e.printStackTrace();
                }
            }

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

6.FileInputStream和FileOutputStream的使用

		//1.定义流
        FileInputStream fis = null;
        try {
    
    
            //2.创建文件
            File srcFile = new File("hello.txt");

            //3.创建流
            fis = new FileInputStream(srcFile);

            //4.读取数据
            byte[] srcs = new byte[5];
            int len;
            while ((len = fis.read(srcs)) != -1){
    
    
                System.out.println(new String(srcs));

            }
        }catch (IOException e){
    
    
            e.printStackTrace();
        }finally {
    
    
            if(fis != null){
    
    
                try {
    
    
                    fis.close();
                }catch (IOException e){
    
    
                    e.printStackTrace();
                }
            }
        }
使用FileInputStream和FileOutputStream实现非文本文件的复制
		//1.定义流
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
    
    
            //2.创建文件
            File srcFile = new File("1.png");
            File desFile = new File("2.png");

            //3.创建流
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(desFile);

            //4.读取数据
            byte[] srcs = new byte[5];
            int len;
            while ((len = fis.read(srcs)) != -1){
    
    
                //System.out.println(new String(srcs));
                fos.write(srcs,0,len);
            }
        }catch (IOException e){
    
    
            e.printStackTrace();
        }finally {
    
    
            if(fis != null){
    
    
                try {
    
    
                    fis.close();
                }catch (IOException e){
    
    
                    e.printStackTrace();
                }
            }

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

7.处理流之一:缓冲流的使用

缓冲流的作用:提高流的读取、写入的速度
原因:内部提供了一个缓冲区

BufferedInputStream和BufferedOutputStream
		//定义流
        FileInputStream fis = null;
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
    
    
            //定义文件
            File srcFile = new File("1.png");
            File desFile = new File("des.png");

            //创造流
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(desFile);
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);

            //复制
            byte[] bytes = new byte[10];
            int len;
            while ((len = bis.read(bytes)) != -1){
    
    
                bos.write(bytes,0,len);
            }

        }catch (IOException e){
    
    
            e.printStackTrace();
        }finally {
    
    
            //关闭流的顺序就像脱衣服一样,先关闭外层的,再关闭内层的
            //在这里,关闭外层的流之后,内层的流会自动关闭,所以也可以不写内层流的关闭
            if(bis != null){
    
    
                try {
    
    
                    bis.close();
                }catch (IOException e){
    
    
                    e.printStackTrace();
                }
            }

            if(bos != null){
    
    
                try {
    
    
                    bos.close();
                }catch (IOException e){
    
    
                    e.printStackTrace();
                }
            }
        }
BufferedReader和BufferedWriter的使用(和上面的一样,不再示例)

这里需要掌握的就是文件的读写,可以使用readLine方法

            String data;
            while ((data = br.readLine()) != null){
    
    
                bw.write(data + "\n");
            }

三.其他流的使用

1.处理流之二:转换流

①转换流属于字符流
②作用:提供字节流与字符流之间的转换

解码:字节、字节数组---------->字符数组、字符串(InputStreamReader)
编码:字符数组、字符串------->字节、字节数组(OuputStreamWriter)
④具体使用什么字符集解码,取决于文件保存时使用的字符集
在这里插入图片描述

在这里插入图片描述

使用InputStreamReader
		//定义流
        FileInputStream fis = null;
        InputStreamReader isr = null;

        try {
    
    
            //创建文件
            File srcFile = new File("hello.txt");

            //创建流
            fis = new FileInputStream(srcFile);
            isr = new InputStreamReader(fis,"UTF-8");

            //读取数据
            char[] chars = new char[5];
            int len;
            while ((len = isr.read(chars)) != -1){
    
    
                System.out.println(chars);
            }
        }catch (IOException e){
    
    
            e.printStackTrace();
        }finally {
    
    
            if(isr != null){
    
    
                try {
    
    
                    isr.close();
                }catch (IOException e){
    
    
                    e.printStackTrace();
                }
            }
        }
综合使用InputStreamReader和OutputStreamWriter(可以改变文件编码)
		//定义流
        FileInputStream fis = null;
        InputStreamReader isr = null;
        FileOutputStream fos = null;
        OutputStreamWriter osw = null;

        try {
    
    
            //创建文件
            File srcFile = new File("hello.txt");
            File desFile = new File("desHelllo.txt");

            //创建流
            fis = new FileInputStream(srcFile);
            isr = new InputStreamReader(fis,"UTF-8");

            fos = new FileOutputStream(desFile);
            osw = new OutputStreamWriter(fos,"gbk");

            //读取数据
            char[] chars = new char[5];
            int len;
            while ((len = isr.read(chars)) != -1){
    
    
                osw.write(chars,0,len);
            }
        }catch (IOException e){
    
    
            e.printStackTrace();
        }finally {
    
    
            if(isr != null){
    
    
                try {
    
    
                    isr.close();
                }catch (IOException e){
    
    
                    e.printStackTrace();
                }
            }

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

2.标准输入输出流、打印流、数据流、随机存取文件流、NIO2中Path、Paths、File类的使用都是了解,用不太到。在这里就不介绍了

三.处理流之三:对象流

1.功能介绍

ObjectInputStream和ObjectOutputStream是用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来

2.序列化与反序列化

序列化:用ObjectOutputStream类保存基本类型数据或对象的机制
反序列化:用ObjectInputStream类读取基本类型数据或对象的机制
注意:ObjectOutputStream和ObjectInputStream不能序列化static和translent修饰的成员变量

3.序列化机制

对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流。从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其他程序获取了这种二进制流,就可以恢复成原来的Java对象

4.使用示例

对象如果能序列化,必须
①实现Serializable或者Externalizable
②当前类提供一个全局常量serialVersionUID。比如

public static final long serialVersionUID = xxxxxxL;

如果类没有显式定义这个静态常量,它的值是Java运行时环境根据类的内部细节自动生成的。若类做了修改(比如加了一个新属性或者新方法),serialVersionUID可能发生变化,所以可能会出现序列化版本不一致的异常。所以建议显式声明。

③除了当前Person类需要实现Serializable接口之外,还必须保证其内部所有属性也必须是可序列化的。(默认情况下,基本数据类型可序列化,所以一般指你的属性中为自定义类的对象的属性实现Serializable接口)

		//1.定义流
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try {
    
    
            //2.创建流(把创建文件相结合)
            fos = new FileOutputStream("ObjectOut.txt");
            oos = new ObjectOutputStream(fos);
            ois = new ObjectInputStream(new FileInputStream("ObjectOut.txt"));

            //3.写出数据
            oos.writeObject(new String("我爱北京"));

            //4.显式刷新
            oos.flush();

            //5.读取数据(反序列化)
            Object obj = ois.readObject();
            System.out.println(obj.toString());//我爱北京
        }catch (IOException | ClassNotFoundException e){
    
    
            e.printStackTrace();
        }finally {
    
    
            if(oos != null){
    
    
                try {
    
    
                    oos.close();
                }catch (IOException e){
    
    
                    e.printStackTrace();
                }
            }
        }

猜你喜欢

转载自blog.csdn.net/afdafvdaa/article/details/113458051