07-IO 流与 File 类
对应原始资料:
JavaSE进阶_day10~day12
一、File 类
java.io.File:文件和目录路径的抽象表示。
1. 构造与常用方法
java
File f = new File("D:/a.txt");
File dir = new File("D:/demo");
f.exists(); // 是否存在
f.isFile(); // 是文件
f.isDirectory(); // 是目录
f.getName();
f.length(); // 字节数
f.getAbsolutePath();
f.lastModified(); // 毫秒时间戳
f.createNewFile(); // 创建文件
f.mkdir(); // 创建单级
f.mkdirs(); // 创建多级目录
f.delete(); // 删除(目录必须为空)
f.renameTo(new File("D:/b.txt"));2. 遍历目录
java
String[] names = dir.list();
File[] files = dir.listFiles();
// 文件名过滤器
File[] txts = dir.listFiles((d, n) -> n.endsWith(".txt"));3. 递归遍历(经典)
java
void find(File dir) {
File[] fs = dir.listFiles();
if (fs == null) return;
for (File f : fs) {
if (f.isFile()) System.out.println(f);
else find(f);
}
}二、IO 流体系
字节流(读写任意文件,.txt/.图片/视频)
├── InputStream
│ ├── FileInputStream
│ ├── BufferedInputStream
│ └── ObjectInputStream(反序列化)
└── OutputStream
├── FileOutputStream
├── BufferedOutputStream
└── ObjectOutputStream(序列化)
字符流(只读写纯文本文件,按字符)
├── Reader
│ ├── FileReader
│ ├── BufferedReader(.readLine())
│ └── InputStreamReader(转换流,指定编码)
└── Writer
├── FileWriter
├── BufferedWriter(.newLine())
└── OutputStreamWriter选型规则
- 纯文本 → 字符流。
- 图片、视频、未知格式 → 字节流。
三、字节流
FileInputStream / FileOutputStream
java
// 读
try (FileInputStream fis = new FileInputStream("a.txt")) {
int b;
while ((b = fis.read()) != -1) System.out.print((char) b);
// 或一次读一个字节数组
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) != -1) {
System.out.println(new String(buf, 0, len));
}
}
// 写
try (FileOutputStream fos = new FileOutputStream("b.txt")) {
fos.write(97);
fos.write("hello".getBytes());
fos.write("world".getBytes(), 0, 3);
}
// 第二参数 append=true 表示追加模式文件拷贝
java
try (FileInputStream fis = new FileInputStream("src.jpg");
FileOutputStream fos = new FileOutputStream("dst.jpg")) {
byte[] buf = new byte[8192];
int len;
while ((len = fis.read(buf)) != -1) fos.write(buf, 0, len);
}四、字节缓冲流
内部维护 8192 字节缓冲区,大幅提升读写效率。
java
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b"));
bos.write(...); bos.flush(); // 主动刷新五、字符流与编码
1. 编码表
- ASCII → ISO-8859-1 → GBK(中文 2 字节) → Unicode(统一码) → UTF-8(变长)。
- IDEA 默认 UTF-8。
2. 转换流(指定编码)
java
InputStreamReader isr = new InputStreamReader(new FileInputStream("gbk.txt"), "GBK");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("out.txt"), "UTF-8");3. FileReader / FileWriter
JDK 11 起 FileReader 可指定编码,等价于转换流简化版。
六、字符缓冲流
java
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
String line;
while ((line = br.readLine()) != null) { // 一次读一行
System.out.println(line);
}
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
bw.write("hello"); bw.newLine(); // 跨平台换行七、对象序列化
把对象转成字节序列持久化到文件 / 网络传输。
1. 序列化
java
class User implements Serializable { // 必须实现
private static final long serialVersionUID = 1L; // 版本号
String name;
transient String password; // transient 不参与序列化
}
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("u.dat"));
oos.writeObject(user);2. 反序列化
java
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("u.dat"));
User u = (User) ois.readObject();注意:
- 静态成员不会被序列化(属于类)。
serialVersionUID不一致会抛InvalidClassException。- 被引用的对象也必须实现 Serializable。
八、其他流(了解)
| 流 | 作用 |
|---|---|
PrintStream / PrintWriter | 打印流,System.out 就是 PrintStream |
DataInputStream / DataOutputStream | 读写基本类型(顺序一致) |
SequenceInputStream | 多个流合并 |
PipedInputStream | 管道流,线程通信 |
commons-io 工具包 | FileUtils、IOUtils(Apache 提供的工具,简化 IO) |
九、try-with-resources
JDK 7 自动关流(资源需实现 AutoCloseable):
java
try (FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt")) {
// 使用
} catch (IOException e) { }
// fr、fw 自动 close()练习建议
- 递归统计某个目录下不同类型文件(.jpg/.txt)的个数。
- 字节流拷贝图片、视频,对比单字节 vs 字节数组 vs 缓冲流的速度。
- 字符缓冲流实现「读取一个文本文件,按行反转后写到另一个文件」。
- 把
List<User>序列化到文件,再反序列化读回来。 - 用
Properties读取.properties配置文件。