Java IO 操作是指在 Java 编程中进行输入和输出的过程,包括读取和写入数据、文件操作、网络通信等。Java IO 是 Java 基础的重要组成部分,通过各种类和接口实现对数据流的操作。Java IO 的核心在于流(Stream)的概念,数据通过流从一个地方传输到另一个地方。
1. Java IO 的基本概念
Java IO 操作主要分为两大类:
- 字节流(Byte Stream):用于处理字节数据,适用于所有类型的文件操作,包括二进制文件(如图片、视频、音频文件)和文本文件。
- 字符流(Character Stream):用于处理字符数据,主要用于处理文本文件,以便更方便地操作 Unicode 字符。
2. 字节流(Byte Stream)
字节流用于处理 8 位字节数据,是最基本的 IO 操作类型。字节流的核心类是InputStream
和OutputStream
。
2.1 InputStream 和 OutputStream
- InputStream:字节输入流的抽象类,用于从源中读取数据。常用子类有
FileInputStream
、BufferedInputStream
、DataInputStream
等。 - OutputStream:字节输出流的抽象类,用于向目标写入数据。常用子类有
FileOutputStream
、BufferedOutputStream
、DataOutputStream
等。
2.1.1 InputStream 的常用方法
int read()
:从输入流中读取一个字节,返回读取的字节,若到达流的末尾,返回 -1。int read(byte[] b)
:将读取的字节存储到指定的字节数组中,返回读取的字节数,若到达流的末尾,返回 -1。void close()
:关闭输入流并释放资源。
2.1.2 OutputStream 的常用方法
void write(int b)
:将指定的字节写入输出流。void write(byte[] b)
:将字节数组中的数据写入输出流。void close()
:关闭输出流并释放资源。
2.1.3 示例:使用字节流进行文件复制
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamExample {
public static void main(String[] args) {
String sourceFile = "input.txt";
String targetFile = "output.txt";
try (FileInputStream fis = new FileInputStream(sourceFile);
FileOutputStream fos = new FileOutputStream(targetFile)) {
int byteData;
while ((byteData = fis.read()) != -1) {
fos.write(byteData);
}
System.out.println("File copied successfully!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 字符流(Character Stream)
字符流用于处理 16 位字符数据,主要用于处理文本文件。字符流的核心类是Reader
和Writer
。
3.1 Reader 和 Writer
- Reader:字符输入流的抽象类,用于从源中读取字符。常用子类有
FileReader
、BufferedReader
、InputStreamReader
等。 - Writer:字符输出流的抽象类,用于向目标写入字符。常用子类有
FileWriter
、BufferedWriter
、OutputStreamWriter
等。
3.1.1 Reader 的常用方法
int read()
:从输入流中读取一个字符,返回读取的字符,若到达流的末尾,返回 -1。int read(char[] cbuf)
:将读取的字符存储到指定的字符数组中,返回读取的字符数,若到达流的末尾,返回 -1。void close()
:关闭输入流并释放资源。
3.1.2 Writer 的常用方法
void write(int c)
:将指定的字符写入输出流。void write(char[] cbuf)
:将字符数组中的数据写入输出流。void close()
:关闭输出流并释放资源。
3.1.3 示例:使用字符流进行文件复制
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CharacterStreamExample {
public static void main(String[] args) {
String sourceFile = "input.txt";
String targetFile = "output.txt";
try (FileReader fr = new FileReader(sourceFile);
FileWriter fw = new FileWriter(targetFile)) {
int charData;
while ((charData = fr.read()) != -1) {
fw.write(charData);
}
System.out.println("File copied successfully using character stream!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. 缓冲流(Buffered Stream)
缓冲流用于提高 IO 操作的效率。通过提供一个内部缓冲区,可以减少实际读写操作的次数。Java 提供了缓冲字节流和缓冲字符流。
4.1 BufferedInputStream 和 BufferedOutputStream
- BufferedInputStream:为字节输入流提供缓冲功能,提高读取效率。
- BufferedOutputStream:为字节输出流提供缓冲功能,提高写入效率。
4.2 BufferedReader 和 BufferedWriter
- BufferedReader:为字符输入流提供缓冲功能,并提供
readLine()
方法,用于读取整行文本。 - BufferedWriter:为字符输出流提供缓冲功能,并提供
newLine()
方法,用于写入新行。
4.2.1 示例:使用缓冲流进行文件复制
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedStreamExample {
public static void main(String[] args) {
String sourceFile = "input.txt";
String targetFile = "output.txt";
try (BufferedReader br = new BufferedReader(new FileReader(sourceFile));
BufferedWriter bw = new BufferedWriter(new FileWriter(targetFile))) {
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
}
System.out.println("File copied successfully using buffered stream!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
5. 数据流(Data Stream)
数据流用于读写 Java 基本数据类型(如int
、float
、double
等)。DataInputStream
和DataOutputStream
可以对基本数据类型进行读写操作,并保证不同平台的数据存取一致性。
5.1 示例:使用 DataInputStream 和 DataOutputStream
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class DataStreamExample {
public static void main(String[] args) {
String file = "data.txt";
// 写数据
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(file))) {
dos.writeInt(123);
dos.writeFloat(45.67f);
dos.writeUTF("Hello, World!");
} catch (IOException e) {
e.printStackTrace();
}
// 读数据
try (DataInputStream dis = new DataInputStream(new FileInputStream(file))) {
int intValue = dis.readInt();
float floatValue = dis.readFloat();
String stringValue = dis.readUTF();
System.out.println("Read values: " + intValue + ", " + floatValue + ", " + stringValue);
} catch (IOException e) {
e.printStackTrace();
}
}
}
6. 对象流(Object Stream)
对象流用于读写对象。Java 的序列化机制允许对象在流中进行传输。ObjectInputStream
和ObjectOutputStream
用来实现对象的序列化和反序列化。
6.1 示例:对象的序列化和反序列化
import java.io.*;
class Person implements Serializable {
private static final long serialVersionUID = 1L;
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 + "}";
}
}
public class ObjectStreamExample {
public static void main(String[] args) {
String file = "person.dat";
// 写对象
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) {
Person person = new Person("John Doe", 30);
oos.writeObject(person);
System.out.println("Person object serialized");
} catch (IOException e) {
e.printStackTrace();
}
// 读对象
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
Person
person = (Person) ois.readObject();
System.out.println("Person object deserialized: " + person);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
7. 文件操作
Java 提供了File
类来操作文件和目录,包括创建、删除、重命名文件和目录,以及检查文件属性等。
7.1 File 类的常用方法
boolean exists()
:检查文件或目录是否存在。boolean isDirectory()
:检查是否是目录。boolean isFile()
:检查是否是文件。boolean mkdir()
:创建目录。boolean delete()
:删除文件或目录。String[] list()
:列出目录中的所有文件和子目录。
7.1.1 示例:文件和目录操作
import java.io.File;
public class FileOperationExample {
public static void main(String[] args) {
File dir = new File("exampleDir");
File file = new File(dir, "exampleFile.txt");
// 创建目录
if (!dir.exists()) {
dir.mkdir();
System.out.println("Directory created: " + dir.getName());
}
// 创建文件
try {
if (!file.exists()) {
file.createNewFile();
System.out.println("File created: " + file.getName());
}
} catch (IOException e) {
e.printStackTrace();
}
// 列出目录中的文件
String[] files = dir.list();
if (files != null) {
System.out.println("Files in directory " + dir.getName() + ":");
for (String f : files) {
System.out.println(f);
}
}
// 删除文件和目录
if (file.delete()) {
System.out.println("File deleted: " + file.getName());
}
if (dir.delete()) {
System.out.println("Directory deleted: " + dir.getName());
}
}
}
8. NIO(New IO)
Java NIO(New IO)是 Java 1.4 中引入的一种新的 IO API,提供了非阻塞 IO 操作、大文件的高效读写、内存映射文件等功能。NIO 的核心概念包括Channel
、Buffer
和Selector
。
8.1 Channel 和 Buffer
- Channel:用于连接数据源和数据目标的通道。常用的通道有
FileChannel
、SocketChannel
等。 - Buffer:用于在通道之间传输数据的容器。常用的缓冲区有
ByteBuffer
、CharBuffer
等。
8.1.1 示例:使用 NIO 复制文件
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class NIOFileCopyExample {
public static void main(String[] args) {
Path sourcePath = Paths.get("input.txt");
Path targetPath = Paths.get("output.txt");
try (FileChannel sourceChannel = FileChannel.open(sourcePath);
FileChannel targetChannel = FileChannel.open(targetPath, java.nio.file.StandardOpenOption.CREATE, java.nio.file.StandardOpenOption.WRITE)) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (sourceChannel.read(buffer) > 0) {
buffer.flip();
targetChannel.write(buffer);
buffer.clear();
}
System.out.println("File copied successfully using NIO!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
9. 总结
Java IO 是一个功能强大的工具集,涵盖了从基本的文件操作到复杂的网络通信等各个方面。掌握 Java IO 是成为高级 Java 开发者的重要步骤。通过理解字节流、字符流、缓冲流、数据流、对象流以及 NIO 的使用,你可以高效地进行各种数据处理任务。