IO流(转换流、打印流、序列化流与反序列化流)

1、转换流

(1)OutputStreamWriter类:

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class TransFormatioDemo {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos0 = new FileOutputStream("E:\IO流\java\221.txt");
        OutputStreamWriter osw0 = new OutputStreamWriter(fos0, "utf-8");
        osw0.write("从一种能量形式变成另一种能量形式电能到机械能的转换");
        osw0.close();

        FileOutputStream fos = new FileOutputStream("E:\IO流\java\121.txt");
        OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");// 系统默认
        osw.write("从一种能量形式变成另一种能量形式电能到机械能的转换");
        osw.close();

    }
}

运行后产生的两个文件的文字格式不同。

(2)InputStreamReader类:

package pers.zxx.Input;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
    FileInputStream in = new FileInputStream("E:\IO流\java\221.txt");
    InputStreamReader isr = new InputStreamReader(in,"utf-8");
    int ch = 0;
    while((ch = isr.read())!=-1){
        System.out.print((char)ch);
    }
    isr.close();
} }

如果设定的字符格式与编译器的格式不同,会出现乱码的情况。

 2、打印流

打印流可以分为:字节打印流PrintStream和字符打印流PrintWriter,都不会抛出IO异常。能够很方便地打印各种数据类型的数据。字符流可以实现自动刷新。

(1)字节打印流PrintStream输出数据:不具有自动刷新功能

import java.io.FileNotFoundException;
import java.io.PrintWriter;

public class PrintWriterDemo {
    public static void main(String[] args) throws FileNotFoundException {
        PrintWriter pw = new PrintWriter("E:\IO流\java\221.txt");
        pw.println("打印流");
        pw.print(0.123);
        pw.close();
    }
}

(2)字符打印流PrintWriter:能够自动刷新的打印流

a、与 PrintStream 类不同,如果启用了自动刷新,则只有在调用 printlnprintf 或 format 的其中一个方法时才可能完成此操作

b、数据目的必须是流对象 OutputStream、Writer,因为构造方法中具有自动刷新功能的只有如下两个:

import java.io.FileNotFoundException;
import java.io.PrintWriter;

public class PrintWriterDemo {
    public static void main(String[] args) throws FileNotFoundException {
        PrintWriter out=new PrintWriter("E:\IO流\java\221.txt");
        PrintWriter pw = new PrintWriter(out,true);
        pw.println("打印流");

    }
}

虽然没有调用close();方法关流,在文件中依旧能够实现打印,说明在构造方法中已经自动刷新。

 3、序列化与反序列化

(1)基本概念:

序列化:将对象中的数据写入到文件。

反序列化:将对象的数据从文件中读取出来。

要实现序列化或反序列化必须实现接口Serializable 。

(2)序列化:

package pers.zxc.xulie;

import java.io.Serializable;

public class Person implements Serializable{
    private String name;
    private int 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 String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }

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

}
package pers.zxc.xulie;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Test {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("E:\IO流\java\2221.txt");

        ObjectOutputStream oos = new ObjectOutputStream(fos);
    
        oos.writeObject(new Person("Tom", 12));

        oos.close();

    }
}

运行结果不能看懂,但是可以通过反序列化将数据读出来。

(3)反序列化:

package pers.zxc.xulie;

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

public class ReadDemo {
    public static void main(String[] args) throws IOException,
            ClassNotFoundException {
        FileInputStream fis = new FileInputStream("E:\IO流\java\2221.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Person obj = (Person) ois.readObject();
        System.out.println(obj.toString());

    }
}

将序列化的结果读了出来。

(4)瞬态关键字transient:

被transient关键字修饰后,属性就不会被序列化。同时,被静态修饰符修饰后的属性也不会被序列化。

package pers.zxc.xulie;

import java.io.Serializable;

public class Person implements Serializable{
    private String name;
    private transient int 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 String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }

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

}
原文地址:https://www.cnblogs.com/zhai1997/p/11367441.html