Java成神路 —— IO特殊操作流

2023-05-07 17:02:59 浏览数 (1)

1.1标准输入流

1. System类中有两个静态的成员变量
  • public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
  • public static final PrintStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
2. 示例代码
代码语言:javascript复制
// Scanner实现   

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

public class Demo {
    public static void main(String[] args) throws IOException {

        //public static final InputStream in:标准输入流
        // InputStream is = System.in;
        // int by;
        // while ((by=is.read())!=-1) {
        // System.out.print((char)by);
        // }

        //如何把字节流转换为字符流?用转换流
        // InputStreamReader isr = new InputStreamReader(is);

        // 使用字符流能不能够实现一次读取一行数据呢?可以
        // 但是,一次读取一行数据的方法是字符缓冲输入流的特有方法
        // BufferedReader br = new BufferedReader(isr);

        BufferedReader br = new BufferedReader(new
                InputStreamReader(System.in));
       
        System.out.println("请输入一个字符串:");
        String line = br.readLine();
        System.out.println("你输入的字符串是:"   line);
        
        System.out.println("请输入一个整数:");
        int i = Integer.parseInt(br.readLine());
        System.out.println("你输入的整数是:"   i);

        //自己实现键盘录入数据太麻烦了,所以Java就提供了一个类供我们使用
        Scanner sc = new Scanner(System.in);
    }
}

1.2 标准输出流

1. System类中有两个静态的成员变量
  • public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
  • public static final PrintStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
2. 输出语句的本质
  • 输出语句的本质:是一个标准的输出流
  • PrintStream ps = System.out;
  • PrintStream类有的方法,System.out都可以使用
3. 示例代码
代码语言:javascript复制
import java.io.PrintStream;

public class Demo {
    public static void main(String[] args) {
        
        //public static final PrintStream out:标准输出流
        PrintStream ps = System.out;
        
        //能够方便地打印各种数据值
        // ps.print("java");
        // ps.print(100);
       
        // ps.println("java");
        // ps.println(100);
        
        //System.out的本质是一个字节输出流
        System.out.print("java");
        System.out.print(100);
        
        System.out.println("java");
        System.out.println(100);
    }
}

1.3 字节打印流

1. 打印流分类
  • 字节打印流:PrintStream
  • 字符打印流:PrintWriter
2. 打印流的特点
  • 只负责输出数据,不负责读取数据
  • 永远不会抛出IOException
  • 有自己的特有方法
3. 字节打印流
  • PrintStream(String fileName):使用指定的文件名创建新的打印流
  • 使用继承父类的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出
  • 可以改变输出语句的目的地 public static void setOut(PrintStream out):重新分配“标准”输出流
4. 示例代码
代码语言:javascript复制
import java.io.IOException;
import java.io.PrintStream;

public class Demo {
    public static void main(String[] args) throws IOException {

        //PrintStream(String fileName):使用指定的文件名创建新的打印流
        PrintStream ps = new PrintStream("myOtherStream\ps.txt");
        
        //写数据
        //字节输出流有的方法
        // ps.write(97);
        
        //使用特有方法写数据
        // ps.print(97);
        // ps.println();
        // ps.print(98);
        ps.println(97);
        ps.println(98);

        //释放资源
        ps.close();
    }
}

1.4 字符打印流

1. 字符打印流构造房方法

方法名

说明

PrintWriter(String fileName)

使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新

PrintWriter(Writerout, boolean autoFlush)

创建一个新的PrintWriter out:字符输出流 autoFlush: 一个布尔值,如果为真,则println , printf ,或format方法将刷新输出缓冲区

2. 示例代码
代码语言:javascript复制
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class Demo {
    public static void main(String[] args) throws IOException {
        
        //PrintWriter(String fileName) :使用指定的文件名创建一个新的PrintWriter,而不需要自动执行行刷新
        // PrintWriter pw = new PrintWriter("myOtherStream\pw.txt");
        
        // pw.write("hello");
        // pw.write("rn");
        // pw.flush();
        // pw.write("world");
        // pw.write("rn");
        // pw.flush();
        // pw.println("hello");
        
        /*
            pw.write("hello");
            pw.write("rn");
        */
       
        // pw.flush();
        // pw.println("world");
        // pw.flush();

       
       
        //PrintWriter(Writer out, boolean autoFlush):创建一个新的PrintWriter
        PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\pw.txt"),true);
        
        // PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\pw.txt"),false);
        pw.println("hello");
        
        /*
            pw.write("hello");
            pw.write("rn");
            pw.flush();
        */
        pw.println("world");
        
        // 释放资源
        pw.close();
    }
}

1.5 对象序列化流

1. 对象序列化介绍
  • 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
  • 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
  • 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
  • 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
2. 对象序列化流: ObjectOutputStream
  • 将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。
  • 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
3. 构造方法

方法名

说明

ObjectOutputStream(OutputStream out)

创建一个写入指定的OutputStream的ObjectOutputStream

4. 序列化对象的方法

方法名

说明

void writeObject(Object obj)

将指定的对象写入ObjectOutputStream

5. 注意事项
  • 一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口
  • Serializable是一个标记接口,实现该接口,不需要重写任何方法
6. 示例代码
代码语言:javascript复制
import java.io.*;

// 学生类
class Student implements Serializable {
    private String name;
    private int age;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{"  
                "name='"   name   '''  
                ", age="   age  
                '}';
    }
}


// 测试类
public class Demo {
    public static void main(String[] args) throws IOException {

        //ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream\oos.txt"));

        //创建对象
        Student s = new Student("小明",18);

        //void writeObject(Object obj):将指定的对象写入ObjectOutputStream
        oos.writeObject(s);

        //释放资源
        oos.close();
    }
}

1.6 对象反序列化流

1. 对象反序列化流: ObjectInputStream
  • ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
2. 构造方法

方法名

说明

ObjectInputStream(InputStream in)

创建从指定的InputStream读取的ObjectInputStream

3. 反序列化对象的方法

方法名

说明

Object readObject()

从ObjectInputStream读取一个对象

4. 示例代码
代码语言:javascript复制
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;


// 学生类
class Student implements Serializable {
    private String name;
    private int age;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}


// 测试类
public class Demo {
    public static void main(String[] args) throws IOException,
            ClassNotFoundException {

        //ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream\oos.txt"));

        //Object readObject():从ObjectInputStream读取一个对象
        Object obj = ois.readObject();
        Student s = (Student) obj;
        System.out.println(s.getName()   ","   s.getAge());

        //资源回收
        ois.close();
    }
}

1.7 serialVersionUID 和 transient

1. serialVersionUID
  • 用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会抛出InvalidClassException异常
  • 如何解决
    • 重新序列化
    • 给对象所属的类加一个serialVersionUID
      • private static final long serialVersionUID = 42L;
2. transient

如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?

  • 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
3. 示例代码
代码语言:javascript复制
import java.io.*;

// 学生类
class Student implements Serializable {

    private static final long serialVersionUID = 42L;
    private String name;
    // private int age;
    private transient int age;

    public Student() {

    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}



// 测试类
public class Demo {
    public static void main(String[] args) throws IOException,
            ClassNotFoundException {
        
        // write();
        read();
    }
    
    //反序列化
    private static void read() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new
                FileInputStream("myOtherStream\oos.txt"));
        Object obj = ois.readObject();
        Student s = (Student) obj;
        System.out.println(s.getName()   ","   s.getAge());
        ois.close();
    }
    
    //序列化
    private static void write() throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new
                FileOutputStream("myOtherStream\oos.txt"));
        Student s = new Student("林青霞", 30);
        oos.writeObject(s);
        oos.close();
    }
}

0 人点赞