JavaSE学习笔记 - I/O流详解

文章目录

  • I/O 概述
  • 字节流继承结构图
  • 字符流继承机构图
  • 字节流
    • OutputStream 与 FileOutputStream(文件流)
    • InputStream 与 FileInputStream(文件流)
  • 字符流
    • Writer 与 FileWriter(文件流)
    • Reader 与 FileReader(文件流)
  • 缓冲流
    • BufferedOutputStream 与 BufferedInputStream
    • BufferedWriter 与 BufferedReader
  • 转换流
    • OutputStreamWriter 与 InputStreamReader
  • 打印流
    • PrintStream 与 PrintWriter
  • 序列化流
    • ObjectOutputStream 与 ObjectInputStream

I/O 概述

  I/O流:对硬盘文件进行读写,输入流就是将硬盘文件的内容读入到内存中使用,输出流就是将内存中的数据读入到硬盘文件中,以便于长期保存。文件是由字符或者字节构成的,所以可以进行写入和读取。所有的文件数据都是以二进制数字的形式保存,都是一个一个的字节,在传输的时候也是以二进制的形式进行数据的传输。

字节流继承结构图

JavaSE学习笔记 - I/O流详解_第1张图片

字符流继承机构图

JavaSE学习笔记 - I/O流详解_第2张图片

字节流

OutputStream 与 FileOutputStream(文件流)

  OutputStream:所有字节流输出流的父类,将制定的字节数据写入硬盘文件中。FileOutputStream:文件专属的流。
  按照字节或者字符的方式读取或写入文件。
JavaSE学习笔记 - I/O流详解_第3张图片

文件的写入

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        OutputStream os = new FileOutputStream("1.txt");
        //写入单个字节
        os.write(97);//a
        //写入多个字节,如果第一个字节是正数默认查询ASCII码表,如果是负数,两个字节组成一个中文,默认查询GBK码表
        byte[] bytes = {
     65, 66, 67};
        os.write(bytes);//ABC
        byte[] bytes1 = {
     -65, -66, -67, 68, 69};
        os.write(bytes1);//烤紻E
        byte[] bytes2 = "啦啦啦".getBytes();
        System.out.println(Arrays.toString(bytes2));
        //UTF-8三个字节一个汉字,GBK两字节一个汉字,故乱码
        os.write(bytes2);//鍟﹀暒鍟?
        os.close();
    }
}

文件的续写与换行

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        OutputStream os = new FileOutputStream("1.txt", true);
        os.write("啦啦啦".getBytes());
        for (int i = 0; i < 5; i++) {
     
            os.write("啦啦啦".getBytes());
            os.write("\r\n".getBytes());
        }
        os.close();
    }
}

InputStream 与 FileInputStream(文件流)

  InputStream:所有字节输入流的父类,可以将文件中的数据加载到内存中。FileInputStream:文件专属的流。
JavaSE学习笔记 - I/O流详解_第4张图片

读取单个字节

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        InputStream is = new FileInputStream("C:\\Users\\17388\\Desktop\\1.txt");//abced
//        int len = is.read();
//        System.out.println(len);//97
//        len = is.read();
//        System.out.println(len);//98
//        len = is.read();
//        System.out.println(len);//99
//        len = is.read();
//        System.out.println(len);//100
//        len = is.read();
//        System.out.println(len);//101
//        len = is.read();
//        System.out.println(len);//-1 到达文件末尾

        int len = 0;
        while((len = is.read()) != -1) {
     
            System.out.println((char) len);
        }//abcde
        is.close();
    }
}

读取多个字节

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        InputStream is = new FileInputStream("1.txt");//abcde
        //一次读取三个字节
//        byte[] bytes = new byte[3];
//        int len = is.read(bytes);
//        System.out.println(len);
//        System.out.println(new String(bytes));//abc
//        len = is.read(bytes);
//        System.out.println(len);
//        System.out.println(new String(bytes, 0, len));//de
//        len = is.read(bytes);
//        System.out.println(len);
//        System.out.println(new String(bytes, 0, len));//StringIndexOutOfBoundsException

        byte[] bytes = new byte[1024];
        int len = 0;
        while((len = is.read(bytes)) != -1) {
     
            System.out.println(len);
            System.out.println(new String(bytes, 0, len));//abcde
        }
        is.close();
    }
}

读取中文

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        InputStream is = new FileInputStream("1.txt");//啦啦啦
        //utf-8是三个字节一个汉字,gbk是两个字节一个汉字,读取时可能会出现问题
        //所以会乱码,后面可以使用字符流来解决
        //或者每次读取三个字节
        byte[] bytes = new byte[3];
        int len = 0;
        while((len = is.read(bytes)) != -1) {
     
            System.out.println(len);
            System.out.println(new String(bytes, 0, len));//�
        }
        is.close();
    }
}

文件复制

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        InputStream is = new FileInputStream("C:\\Users\\17388\\Desktop\\1.txt");//啦啦啦
        OutputStream os = new FileOutputStream("C:\\Users\\17388\\Desktop\\2.txt");
        byte[] bytes = new byte[3];
        int len = 0;
        while((len = is.read(bytes)) != -1) {
     
            os.write(new String(bytes, 0, len).getBytes());
        }
        is.close();
        os.close();
    }
}

字符流

Writer 与 FileWriter(文件流)

JavaSE学习笔记 - I/O流详解_第5张图片

  Writer:所有字符输出流的父类,将指定的字符输出到硬盘文件中。FileWriter:文件专属字符输出流。
文件的写入

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        Writer fw = new FileWriter("1.txt");
        //写入单个字符
        fw.write(97);
        fw.write(97);
        //写入多个字符
        char[] chars = {
     'a', 'b', 'c'};
        fw.write(chars);
        fw.write("啦啦啦");
        //fw.flush();//将内存缓冲区的数据刷新到文件中
        fw.close();//不写flush自动将缓冲区内容刷新到文件中
    }
}

文件的续写与换行

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        Writer fw = new FileWriter("1.txt", true);
        //写入单个字符
        fw.write(97);
        fw.write(97);
        fw.write("\r\n");
        //写入多个字符
        char[] chars = {
     'a', 'b', 'c'};
        fw.write(chars);
        fw.write("\r\n");
        fw.write(chars, 0, 1);
        fw.write("\r\n");
        fw.write("啦啦啦");
        //fw.flush();//将内存缓冲区的数据刷新到文件中
        fw.close();//不写flush自动将缓冲区内容刷新到文件中
    }
}

Reader 与 FileReader(文件流)

  Reader:所有字符输入流的父类,将指定的字符输出到硬盘文件中。FileReader:文件专属字符输入流。
JavaSE学习笔记 - I/O流详解_第6张图片
读取一个字符

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        Reader fr = new FileReader("1.txt");
        int len = 0;
        while((len = fr.read()) != -1) {
     
            System.out.print((char) len);
        }
        fr.close();
    }
}

读取多个字符

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        Reader fr = new FileReader("1.txt");
        int len = 0;
        char[] chars = new char[1024];
        while((len = fr.read(chars)) != -1) {
     
            System.out.print(new String(chars, 0, len));
        }
        fr.close();
    }
}

缓冲流

  缓冲流能够高效的进行读写操作,是对文件流的增强,在创建流对象的时候自动创建一个默认大小的缓冲区数组,在读取数据的时候,缓冲流会将数据一次性读取到缓冲区中,然后内存在读取数据的时候直接从缓冲区中取数据;在进行写入数据的时候先将数据放入缓冲区中,然后在一次性的将数据写入硬盘文件中。这样就减少了系统的I/O次数,从而提高读写的效率。

BufferedOutputStream 与 BufferedInputStream

JavaSE学习笔记 - I/O流详解_第7张图片
JavaSE学习笔记 - I/O流详解_第8张图片

字节缓冲输出流

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("1.txt"));
        bos.write("写入缓冲区".getBytes());
        bos.close();//自动将缓冲区数据刷新到文件中
    }
}

字节缓冲输入流

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("1.txt"));
        byte[] bytes = new byte[2]; //中文乱码,编码问题
        //可以读取超过文件的长度不会造成中文乱码
        int len = 0;
        while((len = bis.read(bytes)) != -1) {
     
            System.out.println(new String(bytes, 0, len));
        }
//        int len = 0;
//        while((len = bis.read()) != -1) {
     
//            System.out.println(len);//无法读中文
//        }
        bis.close();
    }
}

BufferedWriter 与 BufferedReader

JavaSE学习笔记 - I/O流详解_第9张图片
JavaSE学习笔记 - I/O流详解_第10张图片
字符缓冲输出流

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        BufferedWriter bw = new BufferedWriter(new FileWriter("1.txt"));
        bw.write("啦啦啦");
        bw.newLine();//写入换行符,Linux,Window都自动加
        bw.write("啦啦啦");
        //都写入到了缓冲区中
        bw.close();//自动刷新到文件中
    }
}

字符缓冲输入流

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\17388\\Desktop\\1.txt"));
        String line;
        while((line = br.readLine()) != null) {
     
            System.out.println(line);
        }
        br.close();
    }
}

从屏幕读入字符串
  首先我们将字节流转换为字符流,这样就可以以字符为单位进行传输,在使用 BufferedReader 进行包装,就可以使用 readLine 来读取一行字符串。将标准输入读入到缓冲区中,然后我们就可以从缓冲区中获取到相应的数据。

public class Main {
     
    public static void main(String[] args) {
     
        BufferedReader br = null;
        try {
     
            br = new BufferedReader(new InputStreamReader(System.in));
            String s = null;
            while ((s = br.readLine()) != null) {
     
                System.out.println(s);
                if ("exit".equals(s)) break;
            }
        } catch (Exception e) {
     
            e.printStackTrace();
        } finally {
     
            try {
     
                if (br != null) br.close();
            } catch (IOException e) {
     
                e.printStackTrace();
            }
        }
    }
}

转换流

  将字节流转换成字符流

OutputStreamWriter 与 InputStreamReader

JavaSE学习笔记 - I/O流详解_第11张图片
JavaSE学习笔记 - I/O流详解_第12张图片
字节输入流转字符输入流

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("1.txt"), "GBK");
        osw.write("我是XXX");
        osw.close();
    }
}

字节输出流转字符输出流

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\Users\\17388\\Desktop\\1.txt"), "GBK");
        int len = 0;
        while((len = isr.read()) != -1) {
     
            System.out.println((char) len);
        }
        isr.close();
    }
}

打印流

  可以重定向输出,可以将数据直接输出到文件

PrintStream 与 PrintWriter

字节打印流

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        PrintStream ps = new PrintStream("C:\\Users\\17388\\Desktop\\1.txt");
//        ps.write(97);//a
//        ps.println(97);//97
//        ps.println(true);//true

        //重定向输出
        System.setOut(ps);
        System.out.println("输出到文件");

        ps.close();
    }
}

字符打印流

public class Main {
     
    public static void main(String[] args) throws IOException {
     
        PrintWriter pw = new PrintWriter("C:\\Users\\17388\\Desktop\\1.txt");
        pw.write(97);//a
        pw.println(97);//97
        pw.println(true);//true
        pw.close();
    }
}

序列化流

  序列化:将对象以流的形式保存在文件中
  反序列化:将文件中存储的对象,以流的形式读取出来
  首先我们需要自定义一个类,然后实现 S e r i a l i z a b l e Serializable Serializable 序列化接口,这样类对象才能够被序列化。
  如果成员变量被 transient 或者 static 关键字修饰,那么这个成员变量将不能被序列化,如果没有类没有继承序列化接口,那么在进行序列化的时候会报序列化异常,如果我们在类对象中添加了一个唯一的 serialVersionUID,那么如果我们在添加成员变量之后我们依然可以反序列化出这个对象,因为添加一个唯一标识以后表明类没有改变,如果没有这个唯一的 serialVersionUID,那么就表明这个类不是原来的那个 Person 类,从而对象也不能用原来的文件进行反序列化。

ObjectOutputStream 与 ObjectInputStream

序列化

//序列化单个对象
public class Main {
     
    public static void main(String[] args) throws IOException {
     
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\17388\\Desktop\\1.txt"));
        //无法查阅文件,乱码
        oos.writeObject(new Person("sss", 18));
        oos.writeObject(new Person("yyy", 17));
        oos.writeObject(new Person("lll", 16));
        oos.close();
    }
}

//序列化多个对象
public class Main {
     
    public static void main(String[] args) throws IOException {
     
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\17388\\Desktop\\1.txt"));
        Person[] persons = {
     new Person("sss", 18), new Person("yyy", 17), new Person("lll", 16)};
        oos.writeObject(persons);
        oos.close();
    }
}

反序列化

//反序列化单个对象
public class Main {
     
    public static void main(String[] args) throws IOException, ClassNotFoundException {
     
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\17388\\Desktop\\1.txt"));
        Object object = ois.readObject();
        ois.close();
        System.out.println(object);
    }
}

//反序列化多个对象
public class Main {
     
    public static void main(String[] args) throws IOException, ClassNotFoundException {
     
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\17388\\Desktop\\1.txt"));
        Person[] persons = (Person[]) ois.readObject();
        ois.close();
        for (Person person : persons) {
     
            System.out.println(person);
        }
    }
}

你可能感兴趣的:(JavaSE)