全部笔记All notes

第三章:数据输入输出流

阅读 2m 17s2m 17s read

系列导航

流

输入流:从文件中 读 到程序中

输出流:从程序中 写 到文件中

数据源 目的地

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

相关文章