Java 基础-IO、stream 流、文件操作

输入输出流的分类

java.io 包中,包含了输入输出操作所需的类。

I/O 流可以安装不同的标准分类:

  • 按照流的方向分类:
    • 输入流:将信息从代码外部输入代码
    • 输出流:将代码得到的数据输出到文件、网络、内存等地方
  • 按照流的分工分类:
    • 节点流:访问磁盘、网络等获取数据的流,可以直接实例化
    • 处理流:对信息进行加工转换的流,需要基于节点流实例化
  • 按处理数据的类型分类:
    • 面向字符的流:处理字符数据,自动实现 Java 内部格式(16 bit char 类型)与外部格式(UTF-8 等)的转换。基类是 Reader 和 Writer
    • 面向字节的流:处理一般数据,基类是 InputStream 和 OutputStream

输入输出流

字符流

字符输入流 Reader

所有的字符输入流都继承自 Reader 类。

常用的字符输入流有:BufferedReader、InputStreamReader、FilterReader、StringReader、PipedReader、CharArrayReader。

字符输出流 Writer

所有的字符输出流都继承自 Writer 类。

常用的字符输出流有:BufferedWriter、OutputStreamWriter、FilterWriter、StringWriter、PipedWriter、CharArrayWriter。

字节流

字节输入流 InputStream

所有的字节输入流都继承自 Writer 类。

常用的字节输入流有:FileInputStream、FilterInputStream(子类 BufferedInputStream)、ByteArrayInputStream。

字节输出流 OutputStream

所有的字节输出流都继承自 Writer 类。

常用的字节输出流有:FileOutputStream、FilterOutputStream(子类 BufferedOutputStream)、ByteArrayOutputStream。

常用的输入输出流

FileInputStream 和 FileOutputStream

这两个类用于按字节读写文件。

FileInputStream 从文件读取字节数据

可以用用字符串类型的文件名或文件对象创建 FileInputStream 类的对象。

  • 使用字符串类型的文件名创建输入流对象读取文件:
InputStream f = new FileInputStream("C:/java/hello");
  • 使用文件对象来创建输入流对象读取文件。首先得使用 File() 方法来创建一个文件对象:
File f = new File("C:/java/hello");
InputStream out = new FileInputStream(f);

FileInputStream 对象的常用方法:

方法名描述
public void close() throws IOException{}关闭此文件输入流并释放与此流有关的所有系统资源
protected void finalize()throws IOException {}清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法
public int read()throws IOException{}从 InputStream 对象读取一个字节的数据。返回为整数值。如果已经到结尾则返回-1。
public int read(byte[] r) throws IOException{}从输入流读取r.length长度的字节。返回读取的字节数。如果是文件结尾则返回-1。
public int available() throws IOException{}返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取的字节数。返回一个整数值。

FileOutputStream 向文件写字节数据

如果文件不存在,FileOutputStream 会先创建文件。

  • 使用字符串类型的文件名来创建一个输出流对象:
OutputStream f = new FileOutputStream("C:/java/hello")
  • 使用一个文件对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个文件对象:
File f = new File("C:/java/hello");
OutputStream f = new FileOutputStream(f);

FileOutputStream 对象的常用方法:

方法名描述
public void close() throws IOException{}关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。
protected void finalize()throws IOException {}这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常。
public void write(int w)throws IOException{}把指定的字节写到输出流中。注意一次只能写一字节
public void write(byte[] w)把指定数组中w.length长度的字节写到OutputStream中。

示例


import java.io.*;

public class StreamTest {
    public static void main(String[] args) {
        try {
            byte [] arr = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r'};
            OutputStream os = new FileOutputStream("test.txt");
            for (byte i : arr) {
                os.write(i); // 写一个字节到文件
            }
            os.write(arr); // 写字节数组到文件
            os.close();

            File f = new File("test.txt");
            InputStream is = new FileInputStream(f);
            System.out.println(is.read()); // 显示 104
            byte [] arr2 = new byte[10];
            is.read(arr2);
            for (byte i : arr2) {
                System.out.print((char)i);
            }
            is.close();
            is = new FileInputStream(f);
            int size = is.available();

            for (int i = 0; i < size; i++) {
                System.out.print((char)(is.read()));
            }
        } catch (IOException e) {
            System.out.println(e);
        }
    }
}

上面程序的输出为:

104
ello worhehello worhello wor

文件 test.txt 内容为:

hello worhello wor

OutputStreamWriter 和 InputStreamReader

这两个类用于转换字节流和字符流。

OutputStreamWriter

OutputStreamWriter 是将字符流转为字节流的桥梁,可以用指定的编码将字符编码为字节。可以在构造方法中指定字符集,或者默认用操作系统字符集。

使用字符串类型的文件名来创建一个输出流对象:

OutputStreamWriter osw = new OutputStreamWriter(OutputStream out, CharsetEncoder enc)

OutputStreamWriter 对象的常用方法:

方法名描述
void close()关闭流,关闭之前会自动清空
void flush()清空流
String getEncoding()返回当前流的字符编码
void write(char[] cbuf, int off, int len)写入字符数组的一部分
void write(int c)写入一个字符
void write(String str, int off, int len)写入字符串的一部分

InputStreamReader

将字节流转为字符流。读取字节并按照指定的字符集解码为字符。

InputStreamReader(InputStream in, Charset cs)

FileOutputStream 对象的常用方法:

方法名描述
void close()关闭流并释放相关的系统资源
String getEncoding()返回当前流使用的字符集编码
int read()读一个字符
int read(char[] cbuf, int offset, int length)将字符读到数组的指定部分
boolean ready()表示当前流是否就绪,可以随时读数据

示例

import java.io.*;

public class StreamTrans {
    public static void main(String[] args) throws IOException {
        InputStream is = new FileInputStream("test.txt");
        InputStreamReader isr = new InputStreamReader(is);
        char[] arr = new char[10];
        isr.read(arr);
        System.out.println(arr);
        isr.close();
    }
}

FileReader 和 FileWriter

用于按字符读写文件。跟 FileInputStream 和 FileOutputStream 类似。

BufferedReader 和 BufferedWriter

这两个类可以为 I/O 操作提供缓冲区,实现单个字符、数组和字符串的读写。

BufferedReader

继承自 Reader。

比 FileReader 类多了个 readLine() 方法,可以一次读取完整的一行(跨平台)。

BufferedWriter

BufferedWriter 有个跨平台的 newLine() 方法,可以在各个平台实现统一的换行效果。

示例

import java.io.*;

public class BufferedTest {
    public static void main(String[] args) {
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"));
            bw.newLine();
            bw.write("hehe");
            bw.newLine();
            bw.write("hehe");
            bw.flush();
            BufferedReader br = new BufferedReader(new FileReader("test.txt"));
            String line = br.readLine();
            while (line != null) {
                System.out.println(line);
                line = br.readLine();
            }
        } catch (IOException e) {
            System.out.println(e);
        }
    }
}

输出:


hehe
hehe

DataOutputStream 和 DataInputStream

这两个类具有写各种基本数据类型的方法,且各种类型可以跨平台。另外,可以用 size() 方法统计写入的字节数。

DataOutputStream

常用方法:

方法描述
void flush()Flushes this data output stream.
int size()返回当前计数器的值,目前已经写入这个流的字节数
void write(byte[] b, int off, int len)从指定的字节数组 off 偏移处,写 len 个字节到输出流
void write(int b)写入指定的字节(参数 b 的低8位)到输出流
void writeBoolean(boolean v)将布尔数据作为1字节的值写到输出流
void writeByte(int v)将字节数据作为1字节的值写到输出流
void writeBytes(String s)将字符串作为字节序列写到输出流
void writeChar(int v)将字符数据作为2字节的值写到输出流,高位在前
void writeChars(String s)将字符串作为字符序列写到输出流
void writeDouble(double v)通过 Double 类中的 doubleToLongBits 方法将double类型参数转为long 类型后,将其完整的8字节写入输出流,高字节在前
void writeFloat(float v)
void writeInt(int v)
void writeLong(long v)
void writeShort(int v)
void writeUTF(String str)

DataInputStream

可以按照指定的类型读取数据。

示例

import java.io.*;

public class DataStream {
    public static void main(String[] args) throws IOException {
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("test.txt"));
        dos.writeInt(666);
        dos.writeBoolean(false);
        dos.writeChars("hello world");
        dos.flush();
        System.out.println(dos.size()); // 总字节数
        DataInputStream dis = new DataInputStream(new FileInputStream("test.txt"));
        System.out.println(dis.readInt()); // 读整型数据
        System.out.println(dis.readBoolean());
        System.out.println(dis.readByte());
    }
}

标准输入输出流

System 类的静态成员变量,包括:

  • System.in:InputStream 类型的标准输入流,默认是键盘
  • System.out:PrintStream 类型的标准输出流,默认是显示器
  • System.err:PrintStream 类型的标准错误输出流,默认也是输出到显示器

按类型输入输出数据

  • printf 方法格式化输出,其中多了 %n 这个平台无关的换行标志
  • Scanner 类从标准输入流获取指定类型的输入,支持 nextLine()、nextByte() 等方法:
Scanner s = new Scanner(System.in);
int i = s.nextInt();

标准输入输出流重定向

可以将标准流重定向到文件,这样在使用标准输出流时,实际使用的就是文件了。

InputStream in = new BufferedInputStream(new FileInputStream("test.txt"));
OutputStream out = new BufferedOutputStream(new FileOutputStream("out.txt"));
System.setIn(in);
System.setOut(out);
System.setErr(out);

File 类

File 类提供了文件的相关操作,包括:

  • 创建、删除、重命名文件
  • 判断文件是否存在
  • 判断文件的读写权限
  • 设置和查询文件的最新修改时间
import java.io.*;

public class FileTest {
    public static void main(String[] args) {
        File f = new File("test.txt");
        if (f.exists()) { // 判断文件或目录是否存在
            f.delete(); // 删除文件或目录
        } else {
            try {
                f.createNewFile(); // 创建文件
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
}

对象序列化

如果需要在程序结束时保存对象的信息,可以将对象序列化后保存到磁盘上。前提是对象已经实现了 Serializable 接口:

  • ObjectOutputStream 可以用 writeObject 方法把对象写入磁盘
  • ObjectInputStream 可以用 readObject 方法把对象读入程序

对于序列化时不想保存的属性,可以加 transient 修饰。另外 static 类型的变量,不属于任何一个对象,所以也不会序列化。

RandomAccessFile 类

Java 把输入输出都当做字节流处理,所以对随机的文件读写支持的不太好。

  • 可跳转到文件的任意位置读写
  • RandomAccessFile 类实现了 DataInput 和 DataOutput 接口,可以使用普通读写方法
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值