跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Java SE 文件 IO(二):字节流与字符流

Java 中文件 IO 的字节流和字符流操作。详细讲解了 InputStream、OutputStream、Reader、Writer 及其子类的使用方法,包括文件读写、缓冲区刷新、追加模式及异常处理。通过代码示例演示了如何读取图片、文本以及实现文件扫描、复制和内容搜索功能。

CoderByte发布于 2026/3/24更新于 2026/7/2011K 浏览
Java SE 文件 IO(二):字节流与字符流

文件内容的读写——数据流

在 Java 中,文件操作通常使用流对象(Stream)来完成。流类似于水流,可以按不同大小传输数据,例如一次读取 100 个字节或 1 个字节。

1. 字节流

1)InputStream

InputStream 是字节流的输入抽象类,实际使用时需要实例化其子类 FileInputStream。

FileInputStream 构造方法:

签名说明
FileInputStream(File file)使用 File 对象构造文件输入流
FileInputStream(String path)使用文件路径字符串构造输入流

常用方法:

返回类型签名说明
intread()一次读一个字节,读完返回 -1
intread(byte[] b)一次读取字节数组长度的数据,返回 -1 表示结束
intread(byte[] b, int off, int len)从 off 开始读取 len 个字节,返回 -1 表示结束
voidclose()关闭输入流

代码示例:

InputStream inputStream = null;
try {
    inputStream = new FileInputStream("example.png");
} catch (FileNotFoundException e) {
    throw new RuntimeException(e);
} finally {
    if (inputStream != null) {
        inputStream.close();
    }
}

推荐使用 try-with-resources 语法自动关闭资源,因为文件流不属于内存管理范畴,垃圾回收不会自动处理,必须手动关闭以释放文件描述符。

try (InputStream inputStream = new FileInputStream("example.png")) {
     () {
           inputStream.read();
         (a == -) {
            ;
        }
        System.out.println(a);
    }
}
while
true
int
a
=
if
1
break

上述代码每次只读取一个字节,返回值为 0-255 的数值。也可以批量读取:

try (InputStream inputStream = new FileInputStream("example.png")) {
    while (true) {
        byte[] bytes = new byte[20];
        int a = inputStream.read(bytes);
        if (a == -1) {
            break;
        }
        for (int i = 0; i < a; i++) {
            System.out.print(bytes[i] + " ");
        }
        System.out.println();
    }
}

此外,可以使用 Scanner 读取文本内容,但图片等二进制数据建议使用字节流,因为 Scanner 会将字节流转换为字符流,可能破坏二进制编码。

2)OutputStream

OutputStream 是字节流的输出抽象类,通常配合 FileOutputStream 使用。

常用方法:

返回值签名说明
voidwrite(int b)写入单个字节
voidwrite(byte[] b)写入整个字节数组
voidwrite(byte[] b, int off, int len)从 off 开始写入 len 个字节
voidclose()关闭字节流
voidflush()刷新缓冲区,强制将数据写入设备

flush 方法说明: IO 操作较慢,数据通常会先存入缓冲区,待满后再写入设备。flush() 可强制立即写入。

代码示例:

try (OutputStream outputStream = new FileOutputStream("test.txt")) {
    outputStream.write(97); // 'a'
    outputStream.write(98); // 'b'
    outputStream.write(98); // 'b'
}

默认情况下,write 会覆盖原有内容。若需追加写入,需在构造时指定 true:

try (OutputStream outputStream = new FileOutputStream("test.txt", true)) {
    outputStream.write(76); // 'L'
}

如果目标文件不存在,FileOutputStream 会自动创建。

除了直接写入字节,还可以使用 PrintWriter 进行格式化输出:

try (OutputStream outputStream = new FileOutputStream("test4.txt")) {
    PrintWriter printWriter = new PrintWriter(outputStream);
    printWriter.print(98);
    printWriter.println(99);
    printWriter.flush();
}

2. 字符流

字符流通过编码方式直接处理字符,适合处理文本数据。

1)Reader

使用 FileReader 读取文本文件:

public static void main(String[] args) {
    try (Reader reader = new FileReader("test4.txt")) {
        while (true) {
            char[] chars = new char[1024];
            int b = reader.read(chars);
            if (b == -1) {
                break;
            }
            for (int i = 0; i < b; i++) {
                System.out.print(chars[i]);
            }
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

注意保持 Java 运行环境与 IDE 的编码格式一致(如 UTF-8),否则可能出现乱码。

2)Writer

使用 FileWriter 写入文本:

try (Writer writer = new FileWriter("test4.txt")) {
    char[] chars = {'H', 'E', 'l', 'l', 'o'};
    writer.write(chars);
}

3. 练习

1)扫描指定目录并删除匹配文件

扫描目录,查找名称包含指定字符的文件,并询问用户是否删除。

public class Demo2 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要找的目录");
        String rootDir = scanner.next();
        File file = new File(rootDir);
        if (!file.isDirectory()) {
            System.out.println("这不是个目录");
            return;
        }
        System.out.println("请输入要删除的关键字");
        String key = scanner.next();
        find(file, key);
    }

    public static void find(File rootDir, String key) {
        File[] files = rootDir.listFiles();
        if (files == null) {
            return;
        }
        for (File file : files) {
            System.out.println("正在遍历" + file.getAbsolutePath());
            if (file.isFile()) {
                dealFile(file, key);
            } else {
                find(file, key);
            }
        }
    }

    public static void dealFile(File file, String key) {
        if (file.getName().contains(key)) {
            System.out.println("发现文件,是否要删除呢?删除输入 y");
            Scanner scanner = new Scanner(System.in);
            String s = scanner.next();
            if (s.equals("y")) {
                file.delete();
            }
        }
    }
}

2)普通文件复制

实现源文件到目标文件的复制。

public class Demo3 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入源文件路径");
        String src = scanner.next();
        File file = new File(src);
        if (!file.isFile()) {
            System.out.println("输入的不是源文件路径或者源文件不存在");
            return;
        }
        System.out.println("请输入目标文件路径");
        String destPath = scanner.next();
        File file1 = new File(destPath);
        if (!file1.getParentFile().isDirectory()) {
            System.out.println("输入的目标文件路径的父目录不存在");
            return;
        }
        try (InputStream inputStream = new FileInputStream(file);
             OutputStream outputStream = new FileOutputStream(file1)) {
            while (true) {
                byte[] bytes = new byte[1024];
                int a = inputStream.read(bytes);
                if (a == -1) {
                    break;
                }
                outputStream.write(bytes, 0, a);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

3)扫描内容并查找关键字

扫描指定目录,查找文件名或内容包含指定关键字的文件。

public class Demo4 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要搜索的内容,输入目录");
        String src = scanner.next();
        File file = new File(src);
        if (!file.isDirectory()) {
            System.out.println("输入的不是目录");
            return;
        }
        System.out.println("请输入关键字");
        String key = scanner.next();
        find(file, key);
    }

    public static void find(File file, String key) {
        File[] files = file.listFiles();
        if (files == null) {
            return;
        }
        for (File file1 : files) {
            if (file1.isFile()) {
                dealFile(file1, key);
            } else {
                find(file1, key);
            }
        }
    }

    public static void dealFile(File file, String k) {
        if (file.getName().contains(k)) {
            System.out.println("文件名包含" + file.getName());
            return;
        }
        StringBuffer stringBuffer = new StringBuffer();
        try (Reader reader = new FileReader(file)) {
            while (true) {
                char[] chars = new char[1024];
                int a = reader.read(chars);
                if (a == -1) {
                    break;
                }
                stringBuffer.append(chars, 0, a);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (stringBuffer.indexOf(k) >= 0) {
            System.out.println("文件内容包含" + file.getName());
        }
    }
}

目录

  1. 文件内容的读写——数据流
  2. 1. 字节流
  3. 1)InputStream
  4. 2)OutputStream
  5. 2. 字符流
  6. 1)Reader
  7. 2)Writer
  8. 3. 练习
  9. 1)扫描指定目录并删除匹配文件
  10. 2)普通文件复制
  11. 3)扫描内容并查找关键字
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 基于 SpringBoot 的 Java 在线拍卖系统设计与实现
  • Linux 登录前自定义欢迎信息显示
  • OpenClaw 接入自定义模型与 WebUI 智能操作指南
  • PyQt5 基础与常用控件入门教程
  • Python 核心面试考点:装饰器、数据结构与版本差异
  • LLaMA-Factory 合并 LoRA 适配器实战指南
  • 递归、搜索与回溯算法:深入理解记忆化搜索
  • Java IO 流进阶:字符流与字节流的核心应用
  • Nginx 部署前端 Vue 项目实战指南
  • LLM 与 AIGC 融合:编程范式的转变与实践案例
  • C++ 继承机制详解
  • 利用 AI Prompt 优化学术论文逻辑推理的方法与技巧
  • 前端微前端架构:大型项目是解药还是新坑?
  • 使用 InstantID 在 SDXL 模型中生成 AI 写真
  • Python 报错 ModuleNotFoundError: No module named 'distutils' 解决办法
  • MySQL JDBC 连接 URL 参数详解与最佳实践
  • Python 基础语法:数字、表达式与字符串
  • 企业级大模型技术落地场景全解析
  • 基于 SpringBoot + Vue 的时间管理系统设计与实现
  • Python 连接 MySQL 数据库实战指南

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online