系列导航
流
输入流:从文件中 读 到程序中
输出流:从程序中 写 到文件中
数据源 目的地
1. b.txt 写 hello 输出
// bytes 数据源 fos.write() b.txt目的地
File file=new File("E:/b.txt");
FileOutputStream fos=new FileOutputStream(file);
String str="hello"; //数据源
byte[] bytes = str.getBytes();
fos.write(bytes);
fos.close();
// 2.b.txt 读 输入
FileInputStream fis=new FileInputStream(file);
byte[] bytes1=new byte[fis.available()];
fis.read(bytes1);
System.out.println(new String(bytes1));
fis.close();
概述
本章系统梳理 Android/Java 平台的 IO 体系,涵盖字节流/字符流、缓冲流、NIO 与常见文件操作的最佳实践,并提供可直接运行的示例片段。
IO 分类与选型
- 字节流:
InputStream/OutputStream(处理二进制,如图片、文件) - 字符流:
Reader/Writer(处理文本,支持编码) - 缓冲流:
BufferedInputStream/BufferedOutputStream、BufferedReader/BufferedWriter(提升性能) - NIO:
FileChannel、ByteBuffer(高效大文件与随机读写)
选型建议:
- 文本处理优先字符流;二进制优先字节流
- 大文件与性能敏感场景优先 NIO + 缓冲
基础示例
1) 字节流:文件拷贝
public static void copyFile(File src, File dest) throws IOException {
try (FileInputStream fis = new FileInputStream(src);
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream(dest);
BufferedOutputStream bos = new BufferedOutputStream(fos)) {
byte[] buffer = new byte[8192];
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
}
}
2) 字符流:按行读取文本
public static List<String> readLines(File file, Charset cs) throws IOException {
List<String> lines = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), cs))) {
String line;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
}
return lines;
}
3) NIO:大文件高效复制
public static void fastCopy(Path src, Path dest) throws IOException {
try (FileChannel in = FileChannel.open(src, StandardOpenOption.READ);
FileChannel out = FileChannel.open(dest, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
long size = in.size();
long pos = 0;
while (pos < size) {
long transferred = in.transferTo(pos, size - pos, out);
pos += transferred;
}
}
}
Android 特性与注意事项
- 外部存储访问:使用
Storage Access Framework (SAF)或MediaStore;Android 10+ 遵守分区存储(scoped storage) - 权限:读写外部存储需申请运行时权限(Android 13 起变更为照片/视频/音频精细权限)
- 线程:IO 放在
IO Dispatcher/Executors,避免阻塞 UI 线程
Kotlin 协程示例:
withContext(Dispatchers.IO) {
copyFile(srcFile, destFile)
}
最佳实践清单
- 使用 try-with-resources 自动关闭资源
- 合理设置缓冲区大小(8KB~64KB)
- 避免在循环中频繁创建对象
- 明确字符集(如 UTF-8),避免默认平台编码
- 大文件优先 NIO 的 Channel/Buffer 与
transferTo/transferFrom