Java输入输出(IO)流总结

    |     2015年4月3日   |   输入输出(IO)操作   |     0 条评论   |    1775

Java 的 IO 可以按三个轴来记:方向(输入 / 输出)、数据单位(字节 / 字符)、功能(节点流 / 处理流)。四个抽象基类是 InputStream、OutputStream、Reader、Writer。

分类轴 一类 另一类
方向 输入流 输出流
数据单位 字节流 InputStream / OutputStream 字符流 Reader / Writer
功能 节点流(直接连文件等) 处理流(套在节点流上)

一、四个基类的基本方法

InputStream:int read() 读一个字节,返回 -1 表示到末尾;void close() 关闭并释放资源;long skip(long n) 跳过 n 个字节。都可能抛 IOException。

OutputStream:void write(int b) 写一个字节;void flush() 把缓冲区数据刷到目的地。

Writer:write(int c)、write(String str)、write(String str, int offset, int length),以及 flush()。

Reader:int read() 读一个字符,-1 表示到末尾。

二、节点流与缓冲流

访问文件:FileInputStream / FileOutputStream 按字节读写文件;FileReader / FileWriter 按字符读写。输出流构造函数第二个参数为 true 时表示追加到已有文件后面。打开文件可能抛 FileNotFoundException,需要显式捕捉。

缓冲流要套在相应节点流上,提高读写效率。构造方法都要传入对应的基类类型。BufferedReader 提供 readLine() 高效读一行;BufferedWriter 提供 newLine() 写入行分隔符。

三、转换流

转换流把字节流转成字符流,构造时可以指定编码。InputStreamReader 套在 InputStream 上;OutputStreamWriter 套在 OutputStream 上。getEncoding() 可以取得当前编码。

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(文件路径));
String enc = osw.getEncoding();

四、数据流与字节数组流

数据流用来存取 Java 原始类型(long、boolean 等),本身是字节流:DataInputStream 套 InputStream,DataOutputStream 套 OutputStream。读侧有 readBoolean()、readInt()、readUTF()(网络传输常用);写侧方法基本一一对应。

ByteArrayOutputStream 把内容写进内存字节数组,toByteArray() 取出;ByteArrayInputStream 包住一个字节数组,available() 看还剩多少字节。

ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
try {
    dos.writeDouble(Math.random());
    dos.writeBoolean(true);
    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    System.out.println(bais.available());
    DataInputStream dis = new DataInputStream(bais);
    System.out.println(dis.readDouble());
    System.out.println(dis.readBoolean());
    dos.close();
    dis.close();
} catch (IOException e) {
    e.printStackTrace();
}

五、Print 流与 Object 流

Print 流只有输出、没有输入。PrintWriter 对字符,PrintStream 对字节。两者提供重载的 print / println,输出操作不抛异常,并有自动 flush。System.setOut(OutputStream) 可改系统默认输出流。

Object 流相当于把对象序列化后写入或读出。需要序列化的类必须实现 Serializable;transient 标记的成员不参与序列化。主要方法:writeObject(Object)、readObject(),读出是 Object,要强转。

import java.io.*;

public class TestObjectIO {
    public static void main(String args[]) throws Exception {
        T t = new T();
        t.k = 8;
        FileOutputStream fos = new FileOutputStream("d:/share/java/io/testobjectio.dat");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(t);
        oos.flush();
        oos.close();

        FileInputStream fis = new FileInputStream("d:/share/java/io/testobjectio.dat");
        ObjectInputStream ois = new ObjectInputStream(fis);
        T tReaded = (T) ois.readObject();
        System.out.println(tReaded.i + " " + tReaded.j + " " + tReaded.d + " " + tReaded.k);
    }
}

class T implements Serializable {
    int i = 10;
    int j = 9;
    double d = 2.3;
    transient int k = 15;
}

上面把 k 改成 8 再写入,但 k 是 transient,读回来仍是默认 15,不会变成 8。

一句话总结:四个基类定方向和单位,节点流连设备,处理流往上套(缓冲、转换、数据、打印、对象);读到 -1 结束,写完记得 flush / close,序列化记得 Serializable 和 transient。

转载请注明来源:Java输入输出(IO)流总结
本文链接地址:https://ai.zhousir.top/?p=143
回复 取消