Java IO 核心类 File、InputStream/OutputStream 实战总结

目录

一、先搞懂核心定位:它们分别是干嘛的?

[二、File 类:文件 / 目录的「管理员」](#二、File 类:文件 / 目录的「管理员」)

[1. 核心作用](#1. 核心作用)

[2. 常用构造方法](#2. 常用构造方法)

[3. 高频实用方法(背会就能用)](#3. 高频实用方法(背会就能用))

[4. 实战:创建文件 + 遍历目录](#4. 实战:创建文件 + 遍历目录)

(1)安全创建文件(先判断,再创建)

(2)遍历目录下所有文件

[三、字节流:InputStream/OutputStream 数据读写](#三、字节流:InputStream/OutputStream 数据读写)

[1. OutputStream:写数据(FileOutputStream)](#1. OutputStream:写数据(FileOutputStream))

核心方法

实战:自动关闭流的标准写法(推荐)

[2. InputStream:读数据(FileInputStream)](#2. InputStream:读数据(FileInputStream))

核心方法

实战:读取文件内容

[3. 终极实战:文件复制(字节流最经典用法)](#3. 终极实战:文件复制(字节流最经典用法))

四、关键注意事项

五、一张表总结核心区别

总结


做文件操作、数据读写是 Java 开发里最常用、最基础的功能,我刚学的时候总把这几个类搞混,今天就用最直白的话,把 File(文件 / 目录操作)InputStream(字节输入流)OutputStream(字节输出流) 的用法、区别、实战场景一次性讲清楚,不搞花里胡哨的理论,全是能直接用的代码和经验。

一、先搞懂核心定位:它们分别是干嘛的?

先别着急写代码,先分清三个类的「分工」,这是最关键的:

  1. File 类不负责读写数据,只负责「管文件 / 目录本身」------ 创建文件 / 文件夹、删除、重命名、判断是否存在、获取路径等。
  2. InputStream 字节输入流读数据 ------ 从文件、网络等源头,把数据「读进」Java 程序。
  3. OutputStream 字节输出流写数据 ------ 把 Java 程序里的数据「写出」到文件、网络等目标。

一句话总结:File 管文件本身,流管数据读写


二、File 类:文件 / 目录的「管理员」

1. 核心作用

  • 表示一个文件文件夹 的路径(可以是存在的,也可以是不存在的)
  • 操作文件 / 目录的属性:创建、删除、判断类型、获取大小、列出子文件等
  • 绝对不能用它读写文件内容

2. 常用构造方法

直接传路径字符串,支持相对路径(相对于项目根目录)和绝对路径:

java 复制代码
// 相对路径:项目根目录下的 test.txt
File file = new File("test.txt");
// 绝对路径:完整磁盘路径
File file = new File("D:\\test\\demo.txt");
// 拼接路径:父目录 + 子文件名
File parentDir = new File("D:\\test");
File file = new File(parentDir, "demo.txt");

小技巧:Windows 路径用 \\/ 都可以,推荐 / 跨系统通用。

3. 高频实用方法(背会就能用)

这些是开发中 90% 会用到的,直接记:

java 复制代码
File file = new File("test.txt");

// 1. 判断文件/目录是否存在
boolean exists = file.exists();

// 2. 创建文件(不存在则创建,存在返回 false)
boolean createSuccess = file.createNewFile();

// 3. 创建单级文件夹
boolean mkdirSuccess = file.mkdir();
// 创建多级文件夹(比如 a/b/c,推荐用这个)
boolean mkdirsSuccess = file.mkdirs();

// 4. 删除文件/空目录
boolean deleteSuccess = file.delete();

// 5. 判断是文件还是目录
boolean isFile = file.isFile();
boolean isDir = file.isDirectory();

// 6. 获取文件信息
String name = file.getName(); // 文件名
String path = file.getAbsolutePath(); // 绝对路径
long size = file.length(); // 文件大小(字节)

// 7. 列出目录下的所有子文件
File[] files = file.listFiles();

4. 实战:创建文件 + 遍历目录

举两个最常用的实战代码,直接复制就能跑:

(1)安全创建文件(先判断,再创建)
java 复制代码
public static void createFile() throws IOException {
    File file = new File("D:/test/demo.txt");
    // 先判断父目录是否存在,不存在就创建
    if (!file.getParentFile().exists()) {
        file.getParentFile().mkdirs();
    }
    // 创建文件
    if (!file.exists()) {
        file.createNewFile();
        System.out.println("文件创建成功");
    } else {
        System.out.println("文件已存在");
    }
}
(2)遍历目录下所有文件
java 复制代码
public static void listDirectory() {
    File dir = new File("D:/test");
    if (dir.isDirectory()) {
        File[] files = dir.listFiles();
        if (files != null) {
            for (File f : files) {
                System.out.println((f.isFile() ? "文件:" : "目录:") + f.getName());
            }
        }
    }
}

三、字节流:InputStream/OutputStream 数据读写

File 管完文件,读写数据就靠字节流 ,这是 Java IO 最底层的流,所有文件(文本、图片、视频、音频)都能用它读写

先记两个核心规则:

  1. InputStream :抽象类,不能直接 new,用子类 FileInputStream 读文件
  2. OutputStream :抽象类,不能直接 new,用子类 FileOutputStream 写文件
  3. 流用完必须关闭,否则会占用系统资源,推荐用 try-with-resources 自动关闭。

1. OutputStream:写数据(FileOutputStream)

作用:把数据写到文件里,覆盖写 / 追加写都支持。

核心方法
java 复制代码
// 1. 创建流:默认覆盖原文件内容
FileOutputStream fos = new FileOutputStream("test.txt");
// 2. 追加写:第二个参数传 true
FileOutputStream fos = new FileOutputStream("test.txt", true);

// 3. 写数据
fos.write(97); // 写单个字节(97 对应字符 'a')
fos.write("Hello IO".getBytes()); // 写字符串(转字节数组)
fos.write("Hello IO".getBytes(), 0, 5); // 写部分字节

// 4. 刷新缓冲区(强制把数据写到文件)
fos.flush();

// 5. 关闭流(必须做)
fos.close();
实战:自动关闭流的标准写法(推荐)
java 复制代码
public static void writeFile() {
    // try-with-resources:流会自动关闭,不用手动写 close()
    try (FileOutputStream fos = new FileOutputStream("test.txt")) {
        // 写字符串
        fos.write("这是我用字节流写的内容".getBytes());
        System.out.println("写入成功");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

2. InputStream:读数据(FileInputStream)

作用:从文件里把数据读进 Java 程序,一次读一个字节 / 一个字节数组

核心方法
java 复制代码
FileInputStream fis = new FileInputStream("test.txt");

// 1. 读单个字节:返回字节值,读到文件末尾返回 -1
int b = fis.read();

// 2. 读字节数组:返回读到的字节数,末尾返回 -1
byte[] buffer = new byte[1024]; // 缓冲区(常用 1024 字节)
int len = fis.read(buffer);

// 3. 关闭流
fis.close();
实战:读取文件内容
java 复制代码
public static void readFile() {
    try (FileInputStream fis = new FileInputStream("test.txt")) {
        byte[] buffer = new byte[1024];
        int len;
        // 循环读取,直到返回 -1(读完)
        while ((len = fis.read(buffer)) != -1) {
            // 把字节数组转成字符串
            String content = new String(buffer, 0, len);
            System.out.println("读取内容:" + content);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

3. 终极实战:文件复制(字节流最经典用法)

字节流最大的用途就是复制任意格式文件(图片、视频都能复制),这是面试和工作必写的代码:

java 复制代码
public static void copyFile(String srcPath, String destPath) {
    // 源文件:读    目标文件:写
    try (FileInputStream fis = new FileInputStream(srcPath);
         FileOutputStream fos = new FileOutputStream(destPath)) {

        byte[] buffer = new byte[1024 * 4]; // 4KB 缓冲区
        int len;
        // 边读边写
        while ((len = fis.read(buffer)) != -1) {
            fos.write(buffer, 0, len);
        }
        System.out.println("文件复制成功");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// 调用:复制图片
copyFile("D:/test/photo.jpg", "D:/test/photo_copy.jpg");

四、关键注意事项

  1. File 不能读写数据:很多新手犯的错,用 File 试图读文件内容,这是完全错误的。
  2. 流一定要关闭:用 try-with-resources 最安全,自动关闭,不用手动处理异常。
  3. 字节流是万能流:不管是文本、图片、视频、压缩包,都能用 InputStream/OutputStream 处理。
  4. 覆盖写 vs 追加写new FileOutputStream(file) 默认覆盖,加 true 才是追加。
  5. 路径问题:相对路径是相对于项目根目录,绝对路径要写完整,注意父目录不存在会报错。

五、一张表总结核心区别

定位 核心功能 能否读写数据
File 文件 / 目录抽象表示 创建、删除、判断、获取属性 ❌ 不能
FileInputStream 字节输入流(读) 从文件读取字节数据 ✅ 只读
FileOutputStream 字节输出流(写) 向文件写入字节数据 ✅ 只写

总结

  1. File 负责文件 / 目录本身的增删改查,和数据读写无关;
  2. InputStream/OutputStream 是字节流,负责数据读写,支持所有文件类型;
  3. 实战优先用 try-with-resources 自动关闭流,复制文件用字节流最稳妥;
  4. 新手先把这三个类的基础用法练熟,后续学字符流、缓冲流都会轻松很多。

这都是我实际开发中天天用的知识点,没有多余理论,照着代码练两遍,Java IO 基础就稳了。

相关推荐
之歆1 小时前
DAY_25 JavaScript 原型、原型链与值类型/引用类型 ── 深度全解(上)
开发语言·javascript·原型模式
csbysj20201 小时前
C 标准库 - `<time.h>`
开发语言
小陈的进阶之路1 小时前
Python系列课(10)——SQL
开发语言·python·sql
有梦想的小何1 小时前
Cursor AI 编程实战(篇二):Rules、速查与 Adapter/App 全文
java·大数据·elasticsearch·搜索引擎·ai·ai编程
测试员周周1 小时前
【Appium 系列】第03节-驱动初始化 — BaseDriver 的设计与实现
开发语言·人工智能·python·功能测试·appium·测试用例·web app
噢,我明白了3 小时前
表单的完整 CRUD 练习【极简个人记账本】(含前端后端链接mySQL)
java·前端·数据库·mysql
通往曙光的路上3 小时前
mysql1
java
Tigshop开源商城8 小时前
『物流设置+SEO优化』Tigshop开源商城系统 JAVA v5.8.26 版本更新!
java·开源商城系统·tigshop
坚果派·白晓明9 小时前
【鸿蒙PC三方库移植适配框架解读系列】第八篇:扩展lycium框架使其满足rust三方库适配
c语言·开发语言·华为·rust·harmonyos·鸿蒙