Java IO基础:文件操作与流处理
Java IO基础:文件操作与流处理
概述
Java IO(Input/Output)是Java中处理输入输出的核心机制。Java提供了丰富的IO类库,用于处理文件、网络、内存等数据源的读写操作。
1. 文件操作
File类
import java.io.File;
import java.io.IOException;
public class FileExample {
public static void main(String[] args) {
// 创建File对象
File file = new File("test.txt");
File dir = new File("testDir");
File nested = new File("testDir/subDir/file.txt");
// 文件信息
System.out.println("文件名: " + file.getName());
System.out.println("绝对路径: " + file.getAbsolutePath());
System.out.println("父目录: " + file.getParent());
System.out.println("是否存在: " + file.exists());
System.out.println("是否是文件: " + file.isFile());
System.out.println("是否是目录: " + file.isDirectory());
System.out.println("是否可读: " + file.canRead());
System.out.println("是否可写: " + file.canWrite());
// 文件操作
try {
// 创建文件
if (!file.exists()) {
file.createNewFile();
System.out.println("文件已创建");
}
// 创建目录
if (!dir.exists()) {
dir.mkdir();
System.out.println("目录已创建");
}
// 创建多级目录
if (!nested.getParentFile().exists()) {
nested.getParentFile().mkdirs();
System.out.println("多级目录已创建");
}
// 重命名文件
File newFile = new File("renamed.txt");
if (file.renameTo(newFile)) {
System.out.println("文件已重命名");
}
// 删除文件
if (newFile.delete()) {
System.out.println("文件已删除");
}
// 列出目录内容
File dir2 = new File(".");
String[] files = dir2.list();
if (files != null) {
System.out.println("当前目录内容:");
for (String f : files) {
System.out.println("- " + f);
}
}
} catch (IOException e) {
System.out.println("IO异常: " + e.getMessage());
}
}
}
2. 字节流
FileInputStream和FileOutputStream
import java.io.*;
public class ByteStreamExample {
public static void main(String[] args) {
// 写入文件
try (FileOutputStream fos = new FileOutputStream("bytefile.txt")) {
String content = "Hello, Java IO!";
fos.write(content.getBytes());
System.out.println("字节已写入");
} catch (IOException e) {
System.out.println("写入异常: " + e.getMessage());
}
// 读取文件
try (FileInputStream fis = new FileInputStream("bytefile.txt")) {
int data;
while ((data = fis.read()) != -1) {
System.out.print((char) data);
}
System.out.println();
} catch (IOException e) {
System.out.println("读取异常: " + e.getMessage());
}
// 使用缓冲区
try (FileInputStream fis = new FileInputStream("bytefile.txt");
BufferedInputStream bis = new BufferedInputStream(fis)) {
byte[] buffer = new byte[1024];
int bytesRead;
StringBuilder content = new StringBuilder();
while ((bytesRead = bis.read(buffer)) != -1) {
content.append(new String(buffer, 0, bytesRead));
}
System.out.println("缓冲读取: " + content.toString());
} catch (IOException e) {
System.out.println("缓冲读取异常: " + e.getMessage());
}
}
}
文件复制
import java.io.*;
public class FileCopyExample {
public static void copyFile(String source, String dest) throws IOException {
try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(dest)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
}
}
public static void main(String[] args) {
try {
copyFile("source.txt", "dest.txt");
System.out.println("文件复制完成");
} catch (IOException e) {
System.out.println("复制异常: " + e.getMessage());
}
}
}
3. 字符流
FileReader和FileWriter
import java.io.*;
public class CharStreamExample {
public static void main(String[] args) {
// 写入文件
try (FileWriter fw = new FileWriter("charfile.txt")) {
String content = "Hello, Java 字符流!\n第二行内容";
fw.write(content);
System.out.println("字符已写入");
} catch (IOException e) {
System.out.println("写入异常: " + e.getMessage());
}
// 读取文件
try (FileReader fr = new FileReader("charfile.txt")) {
int data;
while ((data = fr.read()) != -1) {
System.out.print((char) data);
}
System.out.println();
} catch (IOException e) {
System.out.println("读取异常: " + e.getMessage());
}
// 使用BufferedReader
try (BufferedReader br = new BufferedReader(new FileReader("charfile.txt"))) {
String line;
StringBuilder content = new StringBuilder();
while ((line = br.readLine()) != null) {
content.append(line).append("\n");
}
System.out.println("BufferedReader读取:\n" + content.toString());
} catch (IOException e) {
System.out.println("BufferedReader异常: " + e.getMessage());
}
// 使用BufferedWriter
try (BufferedWriter bw = new BufferedWriter(new FileWriter("buffered.txt"))) {
bw.write("第一行");
bw.newLine();
bw.write("第二行");
bw.newLine();
bw.write("第三行");
System.out.println("BufferedWriter写入完成");
} catch (IOException e) {
System.out.println("BufferedWriter异常: " + e.getMessage());
}
}
}
4. 转换流
import java.io.*;
public class InputStreamReaderExample {
public static void main(String[] args) {
// 从标准输入读取
try (BufferedReader br = new BufferedReader(
new InputStreamReader(System.in))) {
System.out.print("请输入: ");
String input = br.readLine();
System.out.println("你输入了: " + input);
} catch (IOException e) {
System.out.println("输入异常: " + e.getMessage());
}
// 指定编码
try (BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream("utf8.txt"), "UTF-8"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("编码读取异常: " + e.getMessage());
}
}
}
5. 对象序列化
import java.io.*;
// 可序列化的类
class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
private transient String password; // transient字段不会被序列化
public Person(String name, int age, String password) {
this.name = name;
this.age = age;
this.password = password;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + ", password='" + password + "'}";
}
}
public class SerializationExample {
public static void main(String[] args) {
// 序列化
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("person.ser"))) {
Person person = new Person("Alice", 25, "secret123");
oos.writeObject(person);
System.out.println("对象已序列化");
} catch (IOException e) {
System.out.println("序列化异常: " + e.getMessage());
}
// 反序列化
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("person.ser"))) {
Person person = (Person) ois.readObject();
System.out.println("反序列化对象: " + person);
} catch (IOException | ClassNotFoundException e) {
System.out.println("反序列化异常: " + e.getMessage());
}
}
}
6. 实际应用示例
文件统计工具
import java.io.*;
import java.util.*;
public class FileStats {
public static Map<String, Object> getStats(String filePath) throws IOException {
Map<String, Object> stats = new HashMap<>();
File file = new File(filePath);
stats.put("name", file.getName());
stats.put("size", file.length());
stats.put("exists", file.exists());
stats.put("readable", file.canRead());
stats.put("writable", file.canWrite());
if (file.exists()) {
// 统计字符数
int charCount = 0;
int lineCount = 0;
int wordCount = 0;
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
lineCount++;
charCount += line.length();
wordCount += line.split("\\s+").length;
}
}
stats.put("charCount", charCount);
stats.put("lineCount", lineCount);
stats.put("wordCount", wordCount);
}
return stats;
}
public static void main(String[] args) {
try {
Map<String, Object> stats = getStats("test.txt");
System.out.println("文件统计:");
stats.forEach((key, value) ->
System.out.println(key + ": " + value));
} catch (IOException e) {
System.out.println("统计异常: " + e.getMessage());
}
}
}
7. 最佳实践
- 使用try-with-resources:自动关闭资源
- 使用缓冲流:提高IO性能
- 处理编码:指定正确的字符编码
- 异常处理:妥善处理IOException
- 资源管理:确保资源被正确关闭
总结
Java IO是Java编程中处理输入输出的核心机制。掌握文件操作、字节流、字符流和序列化的使用,是编写健壮Java程序的重要基础。