Java File类 & IO流完全教程
从入门到精通,掌握Java文件操作和输入输出流
📁 File类介绍
什么是File类?
File类是java.io包中的一个类,它代表文件和目录路径名的抽象表示。File类可以用于创建、删除、重命名文件和目录,以及查询文件属性等操作。
File类构造方法
// 通过路径字符串创建File对象
File file1 = new File("C:/test/file.txt");
// 通过父路径和子路径创建
File file2 = new File("C:/test", "file.txt");
// 通过父File对象和子路径创建
File parent = new File("C:/test");
File file3 = new File(parent, "file.txt");
File file1 = new File("C:/test/file.txt");
// 通过父路径和子路径创建
File file2 = new File("C:/test", "file.txt");
// 通过父File对象和子路径创建
File parent = new File("C:/test");
File file3 = new File(parent, "file.txt");
💡 注意: File类只表示文件或目录的路径,并不代表文件本身的内容。要操作文件内容,需要使用IO流。
🔧 File类常用操作
文件和目录操作
public class FileOperationExample {
public static void main(String[] args) {
File file = new File("test.txt");
// 创建文件
try {
if (file.createNewFile()) {
System.out.println("文件创建成功");
}
} catch (IOException e) {
e.printStackTrace();
}
// 文件信息查询
System.out.println("文件名: " + file.getName());
System.out.println("文件路径: " + file.getPath());
System.out.println("绝对路径: " + file.getAbsolutePath());
System.out.println("文件大小: " + file.length() + " 字节");
System.out.println("是否可读: " + file.canRead());
System.out.println("是否可写: " + file.canWrite());
System.out.println("是否是文件: " + file.isFile());
System.out.println("是否是目录: " + file.isDirectory());
System.out.println("是否存在: " + file.exists());
}
}
public static void main(String[] args) {
File file = new File("test.txt");
// 创建文件
try {
if (file.createNewFile()) {
System.out.println("文件创建成功");
}
} catch (IOException e) {
e.printStackTrace();
}
// 文件信息查询
System.out.println("文件名: " + file.getName());
System.out.println("文件路径: " + file.getPath());
System.out.println("绝对路径: " + file.getAbsolutePath());
System.out.println("文件大小: " + file.length() + " 字节");
System.out.println("是否可读: " + file.canRead());
System.out.println("是否可写: " + file.canWrite());
System.out.println("是否是文件: " + file.isFile());
System.out.println("是否是目录: " + file.isDirectory());
System.out.println("是否存在: " + file.exists());
}
}
目录操作示例
public class DirectoryExample {
public static void main(String[] args) {
File dir = new File("myFolder");
// 创建目录
if (dir.mkdir()) {
System.out.println("目录创建成功");
}
// 列出目录内容
File[] files = dir.listFiles();
if (files != null) {
for (File f : files) {
System.out.println(f.getName());
}
}
}
}
public static void main(String[] args) {
File dir = new File("myFolder");
// 创建目录
if (dir.mkdir()) {
System.out.println("目录创建成功");
}
// 列出目录内容
File[] files = dir.listFiles();
if (files != null) {
for (File f : files) {
System.out.println(f.getName());
}
}
}
}
🌊 IO流概述
什么是IO流?
IO流(Input/Output Stream)是Java中用于处理输入输出的机制。流可以看作是一组有序的数据序列,从源端流向目的端。
IO流分类
按数据流向
- 输入流:从源读取数据
- 输出流:向目标写入数据
按数据类型
- 字节流:以字节为单位
- 字符流:以字符为单位
💡 记忆技巧: 字节流用于处理所有类型文件,字符流专门用于处理文本文件。InputStream/OutputStream处理字节,Reader/Writer处理字符。
🔢 字节流 (Byte Streams)
FileInputStream 文件输入流
public class FileInputStreamExample {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("test.txt");
int data;
// 逐个字节读取文件
while ((data = fis.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("test.txt");
int data;
// 逐个字节读取文件
while ((data = fis.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileOutputStream 文件输出流
public class FileOutputStreamExample {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream("output.txt");
String text = "Hello, Java IO!";
// 将字符串转换为字节数组写入文件
fos.write(text.getBytes());
System.out.println("文件写入成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream("output.txt");
String text = "Hello, Java IO!";
// 将字符串转换为字节数组写入文件
fos.write(text.getBytes());
System.out.println("文件写入成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
🔤 字符流 (Character Streams)
FileReader 文件读取器
public class FileReaderExample {
public static void main(String[] args) {
FileReader reader = null;
try {
reader = new FileReader("test.txt");
int data;
// 逐个字符读取文件
while ((data = reader.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
FileReader reader = null;
try {
reader = new FileReader("test.txt");
int data;
// 逐个字符读取文件
while ((data = reader.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileWriter 文件写入器
public class FileWriterExample {
public static void main(String[] args) {
FileWriter writer = null;
try {
writer = new FileWriter("output.txt");
String text = "这是使用FileWriter写入的文本";
writer.write(text);
System.out.println("文件写入成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
FileWriter writer = null;
try {
writer = new FileWriter("output.txt");
String text = "这是使用FileWriter写入的文本";
writer.write(text);
System.out.println("文件写入成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
⚡ 缓冲流 (Buffered Streams)
为什么需要缓冲流?
缓冲流通过在内存中创建缓冲区,减少实际的I/O操作次数,从而提高读写效率。每次读取/写入操作都是针对缓冲区,当缓冲区满时才进行实际的I/O操作。
BufferedReader 示例
public class BufferedReaderExample {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
String line;
// 逐行读取文件,效率更高
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
String line;
// 逐行读取文件,效率更高
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedWriter 示例
public class BufferedWriterExample {
public static void main(String[] args) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {
bw.write("第一行内容");
bw.newLine(); // 换行
bw.write("第二行内容");
bw.flush(); // 刷新缓冲区
System.out.println("文件写入成功");
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {
bw.write("第一行内容");
bw.newLine(); // 换行
bw.write("第二行内容");
bw.flush(); // 刷新缓冲区
System.out.println("文件写入成功");
} catch (IOException e) {
e.printStackTrace();
}
}
}
🎯 对象流 (Object Streams)
序列化对象
class Student implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// getter和setter方法...
}
public class ObjectOutputStreamExample {
public static void main(String[] args) {
Student student = new Student("张三", 20);
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("student.dat"))) {
oos.writeObject(student);
System.out.println("对象序列化成功");
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// getter和setter方法...
}
public class ObjectOutputStreamExample {
public static void main(String[] args) {
Student student = new Student("张三", 20);
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("student.dat"))) {
oos.writeObject(student);
System.out.println("对象序列化成功");
} catch (IOException e) {
e.printStackTrace();
}
}
}
反序列化对象
public class ObjectInputStreamExample {
public static void main(String[] args) {
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("student.dat"))) {
Student student = (Student) ois.readObject();
System.out.println("姓名: " + student.getName());
System.out.println("年龄: " + student.getAge());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("student.dat"))) {
Student student = (Student) ois.readObject();
System.out.println("姓名: " + student.getName());
System.out.println("年龄: " + student.getAge());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
🚀 实战案例
文件复制工具
public class FileCopy {
public static void copyFile(String source, String target) {
try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(target)) {
byte[] buffer = new byte[1024];
int length;
// 使用缓冲区提高复制效率
while ((length = fis.read(buffer)) != -1) {
fos.write(buffer, 0, length);
}
System.out.println("文件复制成功");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
copyFile("source.txt", "target.txt");
}
}
public static void copyFile(String source, String target) {
try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(target)) {
byte[] buffer = new byte[1024];
int length;
// 使用缓冲区提高复制效率
while ((length = fis.read(buffer)) != -1) {
fos.write(buffer, 0, length);
}
System.out.println("文件复制成功");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
copyFile("source.txt", "target.txt");
}
}
配置文件读取器
public class ConfigReader {
public static Properties readConfig(String filename) {
Properties props = new Properties();
try (FileInputStream fis = new FileInputStream(filename)) {
props.load(fis);
System.out.println("配置文件加载成功");
} catch (IOException e) {
e.printStackTrace();
}
return props;
}
public static void main(String[] args) {
Properties config = readConfig("config.properties");
String username = config.getProperty("username");
String password = config.getProperty("password");
System.out.println("用户名: " + username);
System.out.println("密码: " + password);
}
}
public static Properties readConfig(String filename) {
Properties props = new Properties();
try (FileInputStream fis = new FileInputStream(filename)) {
props.load(fis);
System.out.println("配置文件加载成功");
} catch (IOException e) {
e.printStackTrace();
}
return props;
}
public static void main(String[] args) {
Properties config = readConfig("config.properties");
String username = config.getProperty("username");
String password = config.getProperty("password");
System.out.println("用户名: " + username);
System.out.println("密码: " + password);
}
}
📋 快速参考
File类常用方法
- exists() - 判断文件是否存在
- createNewFile() - 创建新文件
- mkdir() - 创建目录
- delete() - 删除文件
- listFiles() - 列出文件
IO流选择指南
- 文本文件 → Reader/Writer
- 二进制文件 → InputStream/OutputStream
- 需要高效 → 缓冲流
- 对象存储 → 对象流
💡 最佳实践
资源管理
- 使用try-with-resources自动关闭流
- 及时关闭IO资源
- 处理IO异常
- 使用缓冲区提高性能
性能优化
- 选择合适的流类型
- 使用缓冲流减少I/O操作
- 合理设置缓冲区大小
- 批量读写数据
❓ 常见问题
Q: File类和IO流有什么区别?
A: File类用于操作文件元数据(创建、删除、查询属性),IO流用于读写文件内容。
Q: 什么时候用字节流?什么时候用字符流?
A: 字节流用于所有类型文件,字符流专门用于文本文件(能正确处理编码)。
Q: 为什么要使用缓冲流?
A: 缓冲流通过减少实际I/O操作次数来提高性能,特别适合大文件操作。
Q: 什么是序列化?
A: 序列化是将对象转换为字节序列的过程,便于存储或传输。