1. 字节流(以字节为单位)
#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
| // 基类: InputStream 和 OutputStream
// 文件操作
FileInputStream fis = new FileInputStream("input.txt");
FileOutputStream fos = new FileOutputStream("output.txt");
// 示例:复制文件
try (FileInputStream fis = new FileInputStream("source.txt");
FileOutputStream fos = new FileOutputStream("target.txt")) {
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
}
// 缓冲流:提高读写效率
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("file.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.txt"))) {
bis.transferTo(bos); // Java 9+
}
// 数据流:读写基本数据类型
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.bin"))) {
dos.writeInt(100);
dos.writeUTF("Hello");
dos.writeDouble(3.14);
}
// 对象流:序列化和反序列化
class User implements Serializable {
private String name;
private int age;
}
// 写入对象
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.obj"))) {
User user = new User("张三", 25);
oos.writeObject(user);
}
// 读取对象
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.obj"))) {
User user = (User) ois.readObject();
}
|
2. 字符流(以字符为单位)
#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| // 基类: Reader 和 Writer
// 文件读写
try (FileReader fr = new FileReader("input.txt");
FileWriter fw = new FileWriter("output.txt")) {
char[] buffer = new char[1024];
int len;
while ((len = fr.read(buffer)) != -1) {
fw.write(buffer, 0, len);
}
}
// 缓冲字符流
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
// 字符串读写
StringReader sr = new StringReader("Hello World");
StringWriter sw = new StringWriter();
|
3. 转换流(字节流转字符流)
#
1
2
3
4
5
6
7
8
9
10
11
12
13
| // InputStreamReader:字节流转换为字符流
try (InputStreamReader isr = new InputStreamReader(new FileInputStream("file.txt"), "UTF-8")) {
char[] buffer = new char[1024];
int len;
while ((len = isr.read(buffer)) != -1) {
System.out.print(new String(buffer, 0, len));
}
}
// OutputStreamWriter:字符流转换为字节流
try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("file.txt"), "UTF-8")) {
osw.write("你好,世界");
}
|
4. 实际应用场景
#
文件复制:
1
2
3
4
5
6
7
8
9
10
11
12
| public static void copyFile(String source, String target) {
try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(target)) {
byte[] buffer = new byte[8192];
int len;
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
|
文本文件读取:
1
2
3
4
5
6
7
8
9
10
11
12
| public static List<String> readLines(String filename) {
List<String> lines = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
String line;
while ((line = br.readLine()) != null) {
lines.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return lines;
}
|
大文件处理:
1
2
3
4
5
6
7
8
9
10
11
12
| public static void processLargeFile(String filename) {
try (BufferedReader br = new BufferedReader(
new FileReader(filename), 8192)) { // 设置更大的缓冲区
String line;
while ((line = br.readLine()) != null) {
// 处理每一行
processLine(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
|
常见使用建议
#
- 总是使用try-with-resources来确保资源正确关闭
- 处理文本文件优先使用字符流
- 处理二进制文件使用字节流
- 大文件操作使用缓冲流提高性能
- 注意指定正确的字符编码
IO流关系图
#
InputStream (字节输入流)
├── FileInputStream(文件输入流)
├── BufferedInputStream(带缓冲)
├── DataInputStream(数据输入流)
└── ObjectInputStream(对象输入流)
OutputStream (字节输出流)
├── FileOutputStream(文件输出流)
├── BufferedOutputStream(带缓冲)
├── DataOutputStream(数据输出流)
└── ObjectOutputStream(对象输出流)
Reader (字符输入流)
├── FileReader(文件读取)
├── BufferedReader(带缓冲)
├── InputStreamReader(转换流)
└── StringReader(字符串输入流)
Writer (字符输出流)
├── FileWriter(文件写入)
├── BufferedWriter(带缓冲)
├── OutputStreamWriter(转换流)
└── StringWriter(字符串输出流)
解压缩示例
#
1. ZIP文件操作
#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| // 压缩文件/目录
public static void zip(String sourcePath, String zipPath) {
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipPath))) {
Path sourceDir = Paths.get(sourcePath);
Files.walk(sourceDir)
.filter(path -> !Files.isDirectory(path))
.forEach(path -> {
ZipEntry zipEntry = new ZipEntry(sourceDir.relativize(path).toString());
try {
zos.putNextEntry(zipEntry);
Files.copy(path, zos);
zos.closeEntry();
} catch (IOException e) {
e.printStackTrace();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
// 解压ZIP文件
public static void unzip(String zipPath, String destPath) {
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipPath))) {
ZipEntry zipEntry;
while ((zipEntry = zis.getNextEntry()) != null) {
Path destFile = Paths.get(destPath, zipEntry.getName());
if (zipEntry.isDirectory()) {
Files.createDirectories(destFile);
} else {
Files.createDirectories(destFile.getParent());
Files.copy(zis, destFile, StandardCopyOption.REPLACE_EXISTING);
}
zis.closeEntry();
}
} catch (IOException e) {
e.printStackTrace();
}
}
|
2. GZIP文件操作
#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| // 压缩文件
public static void gzip(String sourcePath, String gzipPath) {
try (GZIPOutputStream gos = new GZIPOutputStream(new FileOutputStream(gzipPath));
FileInputStream fis = new FileInputStream(sourcePath)) {
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
gos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 解压GZIP文件
public static void ungzip(String gzipPath, String destPath) {
try (GZIPInputStream gis = new GZIPInputStream(new FileInputStream(gzipPath));
FileOutputStream fos = new FileOutputStream(destPath)) {
byte[] buffer = new byte[1024];
int len;
while ((len = gis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
|
- tar.gz文件操作(需要引入Apache Commons Compress):
1
2
3
4
5
| <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.24.0</version>
</dependency>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| // 解压tar.gz文件
public static void untargz(String targzPath, String destPath) {
try (FileInputStream fis = new FileInputStream(targzPath);
GZIPInputStream gis = new GZIPInputStream(fis);
TarArchiveInputStream tais = new TarArchiveInputStream(gis)) {
TarArchiveEntry entry;
while ((entry = tais.getNextTarEntry()) != null) {
Path destFile = Paths.get(destPath, entry.getName());
if (entry.isDirectory()) {
Files.createDirectories(destFile);
} else {
Files.createDirectories(destFile.getParent());
Files.copy(tais, destFile, StandardCopyOption.REPLACE_EXISTING);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
|
- 实际应用示例:
压缩指定目录下的所有文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| public static void zipDirectory(String sourceDir, String zipFile) {
Path sourcePath = Paths.get(sourceDir);
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))) {
Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
String relativePath = sourcePath.relativize(file).toString();
ZipEntry zipEntry = new ZipEntry(relativePath);
zos.putNextEntry(zipEntry);
Files.copy(file, zos);
zos.closeEntry();
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
|
批量解压文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
| public static void batchUnzip(String zipDir, String destDir) {
try {
Files.walk(Paths.get(zipDir))
.filter(path -> path.toString().endsWith(".zip"))
.forEach(zipFile -> {
String destPath = Paths.get(destDir,
zipFile.getFileName().toString().replace(".zip", "")).toString();
unzip(zipFile.toString(), destPath);
});
} catch (IOException e) {
e.printStackTrace();
}
}
|
使用建议:
- 处理大文件时使用缓冲流
- 注意字符编码问题,特别是中文文件名
- 处理压缩文件时注意关闭资源
- 考虑使用进度监听器
- 预防路径穿越漏洞
示例使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| public static void main(String[] args) {
// 压缩文件夹
zip("D:/documents", "D:/backup.zip");
// 解压文件
unzip("D:/backup.zip", "D:/restore");
// 压缩单个文件
gzip("D:/test.txt", "D:/test.txt.gz");
// 解压gz文件
ungzip("D:/test.txt.gz", "D:/test_restored.txt");
// 批量处理
batchUnzip("D:/zips", "D:/extracted");
}
|
补充说明:
- ZIP格式支持多文件压缩
- GZIP通常用于单个文件压缩
- tar.gz在Linux系统中较常见
- 对于大文件压缩,考虑使用异步处理