Java IO 流概述

Java 的 I/O 流是 Java 中处理数据输入输出的基础机制。I/O 流提供了访问外部数据(如文件、网络、键盘等)和将数据写入外部的标准方式。

Java IO 包主要包含 java.io 包下的多种类,主要分为 字节流字符流,分别用于处理不同类型的数据。

1. Java IO 流的分类

1.1 字节流

字节流是按字节处理数据的流,用于处理所有类型的 I/O 操作,尤其是二进制数据(如图片、音频文件等)。字节流类主要包括:

  • InputStream(输入流):FileInputStream, BufferedInputStream, ObjectInputStream
  • OutputStream(输出流):FileOutputStream, BufferedOutputStream, ObjectOutputStream

1.2 字符流

字符流是按字符处理数据的流,主要用于处理文本数据。字符流使用 Unicode 编码,能够处理国际化字符。字符流类主要包括:

  • Reader(读取流):FileReader, BufferedReader, InputStreamReader
  • Writer(写入流):FileWriter, BufferedWriter, OutputStreamWriter

2. 字节流的使用

字节流适用于所有类型的文件,包括图片、音频、视频等。字节流提供了基本的输入输出功能。常用的字节流类包括 FileInputStream, FileOutputStream,以及它们的缓冲流版本 BufferedInputStream, BufferedOutputStream

2.1 示例:使用 FileInputStream 和 FileOutputStream

import java.io.*;

public class ByteStreamExample {
    public static void main(String[] args) {
        try {
            // 创建文件输入流读取文件
            FileInputStream fis = new FileInputStream("source.txt");
            // 创建文件输出流写入文件
            FileOutputStream fos = new FileOutputStream("destination.txt");

            int byteData;
            // 读取文件并写入到新文件
            while ((byteData = fis.read()) != -1) {
                fos.write(byteData);
            }

            fis.close();
            fos.close();
            System.out.println("File copy completed using byte streams.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个示例中,我们使用 FileInputStreamFileOutputStream 对文件进行字节级别的读写操作。每次读取一个字节,将其写入到目标文件中。

2.2 示例:使用 BufferedInputStream 和 BufferedOutputStream

import java.io.*;

public class BufferedByteStreamExample {
    public static void main(String[] args) {
        try {
            // 创建缓冲输入流和输出流
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream("source.txt"));
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("destination.txt"));

            int byteData;
            // 通过缓冲流读取和写入
            while ((byteData = bis.read()) != -1) {
                bos.write(byteData);
            }

            bis.close();
            bos.close();
            System.out.println("File copy completed using buffered byte streams.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个例子中,使用了 BufferedInputStreamBufferedOutputStream,它们通过缓存来优化 I/O 操作,减少了直接读写磁盘的次数,从而提升了性能。

3. 字符流的使用

字符流主要用于文本文件的读写。由于字符流是基于字符处理的,它会自动处理字符编码(如 UTF-8 或 UTF-16),所以字符流更加适合处理文本数据。

3.1 示例:使用 FileReader 和 FileWriter

import java.io.*;

public class CharStreamExample {
    public static void main(String[] args) {
        try {
            // 创建字符输入流读取文件
            FileReader fr = new FileReader("source.txt");
            // 创建字符输出流写入文件
            FileWriter fw = new FileWriter("destination.txt");

            int charData;
            // 读取字符并写入
            while ((charData = fr.read()) != -1) {
                fw.write(charData);
            }

            fr.close();
            fw.close();
            System.out.println("File copy completed using character streams.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个示例中,我们使用 FileReaderFileWriter 来进行字符级别的读写操作。与字节流相比,字符流更适合处理文本数据,尤其是包含国际化字符的文本。

3.2 示例:使用 BufferedReader 和 BufferedWriter

import java.io.*;

public class BufferedCharStreamExample {
    public static void main(String[] args) {
        try {
            // 创建缓冲字符输入流和输出流
            BufferedReader br = new BufferedReader(new FileReader("source.txt"));
            BufferedWriter bw = new BufferedWriter(new FileWriter("destination.txt"));

            String line;
            // 使用缓冲流逐行读取并写入
            while ((line = br.readLine()) != null) {
                bw.write(line);
                bw.newLine();  // 写入换行符
            }

            br.close();
            bw.close();
            System.out.println("File copy completed using buffered character streams.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个例子中,我们使用 BufferedReaderBufferedWriter 来读取和写入文件。BufferedReaderreadLine() 方法允许按行读取文本文件,适用于文本数据处理。

4. 数据流(DataStream)

数据流是字节流的一种,主要用于读取和写入 Java 原生数据类型(如 int, float, double, boolean 等)。通过 DataInputStreamDataOutputStream,可以方便地进行跨平台的二进制数据交换。

4.1 示例:使用 DataInputStream 和 DataOutputStream

import java.io.*;

public class DataStreamExample {
    public static void main(String[] args) {
        try {
            // 创建数据输出流
            DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.dat"));

            // 写入基本数据类型
            dos.writeInt(123);
            dos.writeDouble(45.67);
            dos.writeBoolean(true);

            dos.close();

            // 创建数据输入流
            DataInputStream dis = new DataInputStream(new FileInputStream("data.dat"));

            // 读取基本数据类型
            int num = dis.readInt();
            double d = dis.readDouble();
            boolean bool = dis.readBoolean();

            dis.close();

            System.out.println("Read data: " + num + ", " + d + ", " + bool);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个例子中,我们通过 DataOutputStream 写入基本数据类型,通过 DataInputStream 读取相应的类型。使用数据流可以方便地写入和读取原始数据。

5. 对象流(ObjectStream)

对象流主要用于对象的序列化与反序列化,允许我们将 Java 对象转化为字节流以进行存储或传输。通过 ObjectOutputStreamObjectInputStream,可以将对象序列化后写入文件,并从文件中读取恢复成对象。

5.1 示例:使用 ObjectOutputStream 和 ObjectInputStream

import java.io.*;

class Person implements Serializable {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

public class ObjectStreamExample {
    public static void main(String[] args) {
        try {
            // 创建对象输出流
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"));

            // 创建 Person 对象并序列化
            Person person = new Person("Alice", 30);
            oos.writeObject(person);

            oos.close();

            // 创建对象输入流
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"));

            // 反序列化对象
            Person deserializedPerson = (Person) ois.readObject();

            ois.close();

            System.out.println("Deserialized Person: " + deserializedPerson.getName() + ", " + deserializedPerson.getAge());
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

在这个例子中,我们使用 ObjectOutputStreamPerson 对象序列化到文件,然后使用 ObjectInputStream 从文件中反序列化该对象。需要注意的是,被序列化的类必须实现 Serializable 接口。

6. 总结

  • 字节流:用于处理所有类型的 I/O

,尤其是二进制数据。

  • 例如,FileInputStream, FileOutputStream, BufferedInputStream, BufferedOutputStream
  • 字符流:专门用于处理文本数据,能够自动处理字符编码。
    • 例如,FileReader, FileWriter, BufferedReader, BufferedWriter
  • 数据流:专门用于处理原始数据类型的读写。
    • 例如,DataInputStream, DataOutputStream
  • 对象流:用于对象的序列化和反序列化。
    • 例如,ObjectInputStream, ObjectOutputStream

I/O 流是 Java 中非常重要的概念,广泛用于文件处理、网络通信等场景。理解和掌握这些流的使用方法,可以帮助开发者高效地处理数据。

Java碎碎念 文章被收录于专栏

来一杯咖啡,聊聊Java的碎碎念呀

全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务