Java IO流是Java中用于处理输入输出(Input/Output)的核心机制,是程序与外部设备(如文件、网络、内存等)之间传输数据的桥梁。以下是Java IO流的基础概念及其分类的详细说明:
Java IO流的分类主要基于以下三个维度:
InputStream
:字节输入流的抽象基类。OutputStream
:字节输出流的抽象基类。FileInputStream
:从文件读取字节。FileOutputStream
:向文件写入字节。BufferedInputStream
/BufferedOutputStream
:带缓冲的字节流,提高效率。.txt
、.java
文件),自动处理字符编码(如UTF-8)。Reader
:字符输入流的抽象基类。Writer
:字符输出流的抽象基类。FileReader
:从文件读取字符。FileWriter
:向文件写入字符。BufferedReader
/BufferedWriter
:带缓冲的字符流,支持按行读取。InputStream
、Reader
及其子类。OutputStream
、Writer
及其子类。FileInputStream
:直接读取文件。FileOutputStream
:直接写入文件。BufferedInputStream
:对字节流添加缓冲功能。BufferedReader
:对字符流添加缓冲和按行读取功能。DataInputStream
/DataOutputStream
:支持读写基本数据类型。ObjectInputStream
/ObjectOutputStream
:支持对象的序列化与反序列化。Java IO流的核心类和接口主要位于java.io
包中,以下是关键类的关系:
InputStream
(抽象类)
FileInputStream
:读取文件。BufferedInputStream
:带缓冲的字节输入流。ByteArrayInputStream
:从字节数组读取数据。OutputStream
(抽象类)
FileOutputStream
:写入文件。BufferedOutputStream
:带缓冲的字节输出流。ByteArrayOutputStream
:将数据写入字节数组。Reader
(抽象类)
FileReader
:读取文件。BufferedReader
:带缓冲的字符输入流,支持readLine()
方法。CharArrayReader
:从字符数组读取数据。Writer
(抽象类)
FileWriter
:写入文件。BufferedWriter
:带缓冲的字符输出流,支持newLine()
方法。CharArrayWriter
:将数据写入字符数组。ObjectInputStream
:反序列化对象。ObjectOutputStream
:序列化对象。InputStreamReader
:将字节流转换为字符流(如指定编码格式)。OutputStreamWriter
:将字符流转换为字节流(如指定编码格式)。场景描述:读取和写入文件内容,适用于文本文件、图片、音频等资源的处理。
import java.io.*;
public class FileCopyExample {
public static void main(String[] args) {
File source = new File("source.jpg");
File dest = new File("destination.jpg");
try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(dest)) {
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
System.out.println("文件复制完成。");
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.*;
public class TextFileReadWrite {
public static void main(String[] args) {
File file = new File("example.txt");
// 写入文本
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
writer.write("Hello, Java IO World!");
writer.newLine();
writer.write("This is a sample text file.");
System.out.println("文本已写入文件。");
} catch (IOException e) {
e.printStackTrace();
}
// 读取文本
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
System.out.println("文件内容如下:");
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
场景描述:通过 TCP/IP 协议在客户端和服务器之间传输数据,适用于远程通信、即时消息传输等场景。
import java.io.*;
import java.net.*;
public class TCPServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(8080)) {
System.out.println("服务器已启动,等待连接...");
Socket socket = serverSocket.accept();
try (BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
String clientMessage = in.readLine();
System.out.println("收到客户端消息:" + clientMessage);
out.println("Hello from Server!");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.*;
import java.net.*;
public class TCPClient {
public static void main(String[] args) {
try (Socket socket = new Socket("127.0.0.1", 8080);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()))) {
out.println("Hello from Client!");
String serverResponse = in.readLine();
System.out.println("服务器响应:" + serverResponse);
} catch (IOException e) {
e.printStackTrace();
}
}
}
场景描述:将 Java 对象转为字节流进行存储或传输,适用于数据持久化、远程方法调用(RMI)等场景。
import java.io.*;
public class ObjectSerialization {
public static void main(String[] args) {
Person person = new Person("Alice", 25);
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("person.ser"))) {
oos.writeObject(person);
System.out.println("对象已序列化到文件。");
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
import java.io.*;
public class ObjectDeserialization {
public static void main(String[] args) {
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("person.ser"))) {
Person person = (Person) ois.readObject();
System.out.println("反序列化对象:" + person);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
try-with-resources
语句(Java 7+):自动关闭实现了 AutoCloseable
接口的资源。finally
块中调用 close()
方法。// 使用 try-with-resources 自动关闭流
try (FileInputStream fis = new FileInputStream("file.txt");
FileOutputStream fos = new FileOutputStream("output.txt")) {
int data;
while ((data = fis.read()) != -1) {
fos.write(data);
}
} catch (IOException e) {
e.printStackTrace();
}
IOException
IOException
(如文件不存在、权限不足、磁盘空间不足等)。try-catch
捕获异常,并记录日志或提示用户。try {
// IO 操作代码
} catch (FileNotFoundException e) {
System.err.println("文件未找到: " + e.getMessage());
} catch (IOException e) {
System.err.println("IO 异常: " + e.getMessage());
}
FileInputStream
/FileOutputStream
等节点流效率较低,频繁的磁盘读写会增加 I/O 开销。BufferedInputStream
/BufferedOutputStream
或 BufferedReader
/BufferedWriter
)。try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"), 8192)) {
String line;
while ((line = reader.readLine()) != null) {
// 处理每一行
}
} catch (IOException e) {
e.printStackTrace();
}
InputStream
/OutputStream
):适用于二进制数据(如图片、音频)。Reader
/Writer
):适用于文本数据(如 .txt
文件),自动处理字符编码。FileInputStream
/FileOutputStream
)。FileReader
/FileWriter
)。// 读取二进制文件(图片)
try (FileInputStream fis = new FileInputStream("image.jpg")) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
// 处理字节数组
}
} catch (IOException e) {
e.printStackTrace();
}
InputStreamReader
/OutputStreamWriter
指定编码(如 UTF-8)。// 指定 UTF-8 编码读取文件
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream("file.txt"), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
// 处理文本
}
} catch (IOException e) {
e.printStackTrace();
}
File
类检查文件是否存在、是否可读/写。File.separator
或 Paths.get()
。File file = new File("path/to/file.txt");
if (file.exists() && file.canRead()) {
try (FileReader reader = new FileReader(file)) {
// 读取操作
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.err.println("文件不存在或无法读取");
}
BufferedWriter
/PrintWriter
等缓冲流时,数据可能滞留在缓冲区未写入目标。flush()
方法强制刷新缓冲区。close()
会调用 flush()
)。try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
writer.write("Hello");
writer.flush(); // 手动刷新
writer.newLine(); // 写入换行符
} catch (IOException e) {
e.printStackTrace();
}
synchronized
块)。RandomAccessFile
)。synchronized (fileLock) {
try (FileWriter writer = new FileWriter("shared.txt", true)) {
writer.write("Thread-safe write\n");
} catch (IOException e) {
e.printStackTrace();
}
}
FileChannel
进行内存映射(MappedByteBuffer
)。// 分块读取大文件
try (FileInputStream fis = new FileInputStream("largefile.txt")) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
// 处理分块数据
}
} catch (IOException e) {
e.printStackTrace();
}
../
等特殊字符,导致越权访问。File.getCanonicalPath()
)。String userInputPath = "user/../etc/passwd";
File file = new File("/safe/directory/" + userInputPath);
File normalizedFile = file.getCanonicalFile();
if (normalizedFile.getParentFile().getPath().startsWith("/safe/directory")) {
// 安全访问
} else {
throw new SecurityException("非法路径");
}
Java IO流是程序与外部世界交互的核心机制,通过灵活的分类和组合,能够高效处理各种数据传输需求。掌握字节流、字符流、缓冲流及对象流的使用,是开发文件处理、网络通信等应用的基础。