Java基础之特殊操作流

296 阅读4分钟

「这是我参与2022首次更文挑战的第30天,活动详情查看:2022首次更文挑战

一、标注输入输出流

  • System类中有两个静态的成员变量:
    • public static final InputStream in:标准输入流,通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
    • public static final PrintStream out:标准输出流,通常该流对应于显示输出或由主机环境或用户指定的另一个输入源
package test;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

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);
        br.close();
    }
}

二、打印流

  • 打印流分类
    • 字节打印流:PrintStream
    • 字符打印流:PrintWriter
  • 打印流特点
    • 只负责输出数据,不负责读取数据
    • 有自己特有方法
  • 字节打印流
    • PrintStream(String fileName):使用指定的文件名创建新的打印流
    • 使用继承父类的方法写数据,查看时会转码;使用自己特有方法写数据,查看的数据原样输出
package test;

import java.io.*;

public class Demo {
    public static void main(String[] args) throws  IOException {
     //PrintStream(String fileName):使用指定的文件名创建新的打印流
        PrintStream ps = new PrintStream("E:\\test\\java.txt");

        /*ps.print(1);
        ps.print(2);*/
        //12没有换行

        ps.println(97);
        ps.println(87);
        //97
        //87
        ps.close();
    }
}
  • 字符打印流
方法名说明
PrintWriter(String fileName)使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新
PrintWriter(Writer out,boolean autoFlush)创建一个新的PrintWriter;out:字符输出流,autoFlush:一个布尔值,如果为==true==,则println,printf,或format方法将刷新输出缓冲区
package test;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class Demo {
    public static void main(String[] args) throws IOException {
        //1,PrintWriter(String fileName)
/*        PrintWriter pw = new PrintWriter("E:\\test\\java.txt");

        *//*pw.write("hello");
        pw.write("\r\n");
        pw.flush();
        pw.write("hello");
        pw.write("\r\n");
        pw.flush();*//*
        *//*hello
        hello*//*

        pw.println("hello"); //换行
        pw.flush();
        pw.println("hello");
        pw.flush();*/

        //2,PrintWriter(Writer out,boolean autoFlush)
        PrintWriter pw = new PrintWriter(new FileWriter("E:\\test\\java.txt",true));

        pw.println("hello");
        pw.println("hello"); //构造方法自动刷新了
        
        pw.close();
    }
}

三、对象序列化

  • 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象 这种机制就是使用一个字节序列表示个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息字节序列写到文件之后,相当于文件中持久保存了一个对象的信息 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化

  • 要实现序列化和反序列化就要使用对象序列化流和对象反序列化流:

    • 对象序列化流: ObjectOutputStream
    • 对象反序列化流: ObjectlnputStream

3.1 对象序列化流

  • 对象序列化流:ObjectOutputStream

  • 将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取 (重构)对象。可以通过使用流的文件来实现对象的持久存储。如果流是网络套接字流, 则可以在另一个主机上或另一个进程中重构对象

  • 构造方法

方法名说明
ObjectOutputStream(OutputStream out)创建一个写入指定的OutputStream的ObjectOutputStream
  • 序列化对象的方法
方法名说明
void writeObject(Object obj)将指定的对象写入ObjectOutputStream
  • 注意:

  • 一个对象要想被序列化,该对象所属的类必须必须实现 Serializable [ˈsɪərɪlaɪzbl]接口

  • Serializable是一个标记接口,实现该接口,不需要重写任何方法

3.2 对象反序列化流

  • 对象反序列化流:ObjectInputStream
  • ObjectInputStream反序列化前先使用ObjectOutputStream编写的原始数据和对象
  • 构造方法
方法名说明
ObjectInputStream(InputStream in)创建从指定InputStream读取的ObjectInputStream
  • 反序列化对象的方法
方法名说明
Object readObject()从ObjectInputStream读取一个对象
  • 范例
package test;


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Demo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //ObjectInputStream(InputStream in) 	创建从指定InputStream读取的ObjectInputStream
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\test\\java.txt"));

        //Object readObject() 	从ObjectInputStream读取一个对象
        Student s = (Student) ois.readObject();;
        System.out.println(s.getName()+","+s.getAge()); //小白,10
        ois.close();
    }
}

3.3 注意事项

1、用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?

  • 会出问题, 抛出InvalidClassException异常

2、如果出问题了,如何解决呢?

  • 给对象所属的类加一 个serialVersionUIDprivate static final long serialVersionUID = 42L;

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

  • 给该成员变量加transient [ˈtrænziənt] 关键字修饰,该关键字标记的成员变量不参与序列化过程:private transient int age; (age不会参加序列化)