Java 文件IO :File 文件类、字节流、字符流讲解

📚 目录

  • [1. File 文件操作类详解](#1. File 文件操作类详解)
    • [1.1 构造方法](#1.1 构造方法)
    • [1.2 方法](#1.2 方法)
  • [2. InputStream 字节输入流与OutputStream 字节输出流](#2. InputStream 字节输入流与OutputStream 字节输出流)
    • [2.1 构造方法](#2.1 构造方法)
    • [2.2 read](#2.2 read)
    • [2.3 write](#2.3 write)
  • [3. FileReader字符输入流与FileWrite字符输出流](#3. FileReader字符输入流与FileWrite字符输出流)
    • [3.1 构造方法](#3.1 构造方法)
    • [3.2 read](#3.2 read)
    • [3.3 write](#3.3 write)
  • [4. PrintWriter便捷打印输出流](#4. PrintWriter便捷打印输出流)
    • [4.1 构造方法](#4.1 构造方法)
    • [4.2 常用方法](#4.2 常用方法)

前言:

  在 Java IO 体系当中,我们首先需要分清一个核心概念:File 对象只能够管理文件路径、文件属性,不具备读取和写入文件内部数据的能力。

  真正负责传输文件数据的是 IO 流,IO 流分为字节流、字符流两大类。字节流适配全部格式的文件;字符流专门服务于纯‑文本文件,可以自动处理编码,减少中文乱码问题。下面顺着目录逐层讲解。

1. File 文件操作类详解

1.1 构造方法
签名 说明
File(File parent, String child) 传入父File对象 + 子文件名称
File(String pathname) 直接传入文件路径字符串,可以是绝对路径也可以是相对路径
File(String parent, String child) 拆分父目录路径、子文件名

 日常开发中文件中最常使用的构造方法是:File(String pathname)

 当我们创建完对象之后,就可以通过方法对对象进行一系列的操作;
[🔙 返回目录](#🔙 返回目录)


1.2 方法

 这里我将所有 方法分成信息获取方法状态判断方法创建‑删除‑遍历方法判断用户是否有条件方法四类,

 第一类:信息获取方法:

返回类型 方法 功能说明
String getName() 获取文件 / 文件夹名称,只拿名字,不带目录
String getParent() 获取父目录路径字符串
String getPath() 获取构造 File 时传入的原始路径(相对 / 绝对取决于构造参数)
String getAbsolutePath() 获取文件完整绝对路径
String getCanonicalPath() 获取规范化之后的绝对路径,会解析 .../、./ 这类相对符号

 此处我们具体讲解:getAbsolutePathgetCanonicalPath的区别

 假设我们的文件路径为:javastudio/Java20260807/test.txt这一个文件的路径

 如果我们同时调用这两个方法得到的结果都是一样的;

 此时我们区分不出任何区别,当我们将构造方法中写成相对路径时:

 此时就能很清楚的看见区别:

getAbsolutePath:相当于在获取到父目录的情况下对字符串进行拼接

getCanonicalPath:在获取到绝对路径时,对绝对路径中多余的符号进行优化消除

 第二类:状态判断方法

返回类型 方法 功能说明
boolean exists() 判断磁盘当中该路径下的文件或者文件夹是否真实存在
boolean isFile() 判断当前路径是不是普通文件(txt、图片等,不是文件夹)
boolean isDirectory() 判断当前路径是否为文件夹(目录)

 第三类:创建‑删除‑遍历方法

返回类型 方法 功能说明
boolean createNewFile() 根据 File 对象,自动创建一个空文件。成功创建后返回 true
boolean delete() 根据 File 对象,删除该文件。成功删除后返回 true
void deleteOnExit() 根据 File 对象,标注文件将被删除,删除动作会到 JVM 运行结束时才会进行
String\[\] list() 返回 File 对象代表的目录下的所有文件名
File\[\] listFiles() 返回 File 对象代表的目录下的所有文件,以 File 对象表示
boolean mkdir() 创建 File 对象代表的目录
boolean mkdirs() 创建 File 对象代表的目录,如果必要,会创建中间目录
boolean renameTo(File dest) 进行文件改名,也可以视为我们平时的剪切、粘贴操作

 renameTo方法操作时,如果我们当前路径是一样的,但是此时的操作就是修改名字:

 例如:

 此时就会将名字修改为test1.txt

 处于不同目录下,就会触发移动操作:

 例如:

 我们创建:aaa的路径并移动到aaa路径下;

deleteOnExit执行当前操作时,不会立刻删除文件,而是在JVM运行结束时删除;

 第四类:判断用户是否有条件方法

返回类型 方法 功能说明
boolean canRead() 判断用户是否对文件拥有可读权限
boolean canWrite() 判断用户是否对文件拥有可写权限

 此处取决有用户有一个怎么样的用户权限,类似于word文档中的权限,我们可以查看是可读还是可写权限;
[🔙 返回目录](#🔙 返回目录)


2. InputStream 字节输入流与OutputStream 字节输出流

2.1 构造方法
签名 说明
FileInputStream(File file) 利用 File 构造文件输入流
FileInputStream(String name) 利用文件路径构造文件输入流
java 复制代码
//方式1:传入File对象
File file = new File("test.txt");
InputStream in1 = new FileInputStream(file);

//方式2:传入路径字符串
InputStream in2 = new FileInputStream("test.txt");

 我们可以直接new一个FileInputStream对象也可以使用Reader抽象类来实现向上转型的写法,企业常规写法:

java 复制代码
Reader reader = new FileReader("note.txt");

 同理:OutputStream的构造方法和InputStream类似:

签名 说明
OutputStream(File file) 利用 File 构造文件输出流
OutputStream(String name) 利用文件路径构造文件输出流

[🔙 返回目录](#🔙 返回目录)


2.2 read

read方法进行读操作,Java中实现了3个read方法的重载操作:

修饰符及返回值类型 方法签名 说明
int read() 读取一个字节的数据,返回‑1 代表已经全部读完了
int read(byte\[\] b) 最多读取 b.length 字节的数据到 b 中,返回实际读到的数量;‑1 代表已经读完了
int read(byte\[\] b, int off, int len) 最多读取 len 字节的数据放到 b 数组从 off 的位置开始,返回实际读到的数量;‑1 代表已经读完了
void close() 关闭字节流

 例如:此时我们在E:/javastudio/Java20260807/test.txt当前文件中写入ABCEDFG这个数据;

 通过Input Stream来进行读取;

 当读取到文件末尾时,会返回一个-1的值;

 此处我们也可以传入一个输出型参数:

 Java由于当时设计的局限性,一个方法只能返回一个值,这就导致如果我想要返回多个值的时候,就没有办法进行返回,采用数组这样的输出型参数,能有效解决这类问题:

 形如这样的操作就能有效解决返回多个值的问题;
[🔙 返回目录](#🔙 返回目录)


2.3 write

 write也有3个Java官方实现的重载方法:

修饰符及返回值类型 方法签名 说明
void write(int b) 写入单个字节的数据
void write(byte\[\] b) 将 b 字节数组当中的数据全部写入输出流
void write(byte\[\] b, int off, int len) 将 b 字节数组里从 off 下标开始的数据写入流,一共写入 len‑个字节
void close() 关闭字节流
void flush() 重要:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中。

 例如此时:我们向E:/javastudio/Java20260807/test.txt文件中写入hello world!!;

 我们也可以在构造方法中添加一个参数true

 此时,我们在进行下一次写入数据的时候,就不会清空文件中的内容;
[🔙 返回目录](#🔙 返回目录)


3.FileReader字符输入流与FileWrite字符输出流

3.1 构造方法
签名 说明
FileWriter(File file) 根据File对象创建字符输出流,默认覆盖写入
FileWriter(String fileName) 根据文件路径创建字符输出流,默认覆盖写入
FileWriter(File file, boolean append) append=true 开启文件末尾追加模式
FileWriter(String fileName, boolean append) 路径形式,设置是否追加写入

 当然我们也可以使用ReadWriter来实现多态,这也是日常开发中常使用的方法;

java 复制代码
//父类引用指向子类对象
Reader in = new FileReader("test.txt");
Writer out = new FileWriter("out.txt");

[🔙 返回目录](#🔙 返回目录)


3.2 read

 同理read方法中也提供了3个重载的方法:

方法签名 返回值 详细说明
public int read() int 读取单个字符; 读到文件结尾返回 -1; 正常返回该字符对应的 int 编码值
public int read(char\[\] cbuf) int 将读取到的字符存入字符数组 cbuf; 返回本次成功读取到的字符数目; 无数据返回 -1
public int read(char\[\] cbuf, int off, int len) int off:数组起始存放下标 len:最多读取字符数量 只往数组指定区间填充读取内容

 例如:此时我们在E:/javastudio/Java20260807/test.txt当前文件中写入:

 此时我们可以进行读操作:

 使用方法和InputStream类似,也能传入输出型参数;


[🔙 返回目录](#🔙 返回目录)


3.3 write

write也提供了多个重载的方法:

方法签名 返回值 详细说明
public void write(int c) void 写入单个字符;传入字符对应的 int 编码
public void write(char\[\] cbuf) void 写入整个字符数组当中全部字符
public void write(char\[\] cbuf, int off, int len) void off‑数组起始下标,len‑写入长度;写入数组指定区间
public void write(String str) void 直接写入字符串,字符流独有的便捷方法
public void write(String str, int off, int len) void 写入字符串指定下标区间的内容

 具体使用方法,与OutStream类似,这里不过多进行讲解;

  1. FileWriter 具备缓冲区,write 之后数据暂存内存,必须 flush () 或者 close () 才会把数据落地磁盘;
  2. 构造方法开启追加模式 new FileWriter("xxx.txt",true),不会清空旧文件;
  3. 字节流没有直接写入字符串的重载,这是字符流的优势。

[🔙 返回目录](#🔙 返回目录)


4 PrintWriter便捷打印输出流

 FileWriter属于基础字符输出流,只能够写入字符、字符数组、字符串。

 如果需要写入数字、布尔值,我们需要手动拼接字符串转换:

java 复制代码
fileWriter.write(666 + "");

 而PrintWriter 是增强型装饰字符输出流 ,专门用来简化文本写入,能够自动将 int、double、boolean、对象转换成字符串写入文件,适合书写日志、导出文本。

字节流PrintWriter选取:

  1. 视频、图片、压缩包 → 使用字节流
  2. txt、日志、配置文件 → 使用字符流,优先选用 PrintWriter

4.1 构造方法
构造方法 作用说明
PrintWriter(String fileName) 根据文件路径创建打印流
PrintWriter(Writer out) 包装普通字符输出流 FileWriter
PrintWriter(Writer out, boolean autoFlush) 开启自动刷新;println、printf 执行之后自动刷新缓冲区

[🔙 返回目录](#🔙 返回目录)


4.2 常用方法
方法签名 返回值 详细说明
void print(Object obj) void 输出数据,不会自动换行,内部自动转为字符串
void println(Object obj) void 输出数据并且自动换行;开启自动刷新时刷新缓冲区
void printf(String format, Object... args) void 格式化输出文本,%d、%s、%f占位符
void write(int c) void 写入单个字符,不会自动转换数字
void write(char\[\] cbuf) void 写入完整字符数组
void write(String str) void 写入字符串
void flush() void 强制刷新缓冲区,内存数据写入磁盘
void close() void 关闭流,关闭前自动刷新缓冲区

  1. print() / println():
     底层调用 String.valueOf(),自动把数字、布尔、对象转为文本。
     pw.println(97) 写入文件内容为字符串97
  2. write(int c):
     把参数当作字符编码,写入对应字符。
     pw.write(97) 写入文件内容为字符a

例如;

注意事项:

  1. print() 就算开启自动刷新,也不会刷新缓冲区;只有 println、printf 触发自动刷新
  2. 字符流带有缓冲区,忘记 flush/close,文件内容为空;
  3. PrintWriter 只是装饰流,底层依旧依赖 FileWriter 完成文件写入。

[🔙 返回目录](#🔙 返回目录)


相关推荐
天天爱吃肉82181 小时前
行业笔记|高压连接器瞬态接触退化通用检测方法论
人工智能·笔记·python·功能测试·学习·汽车
云烟成雨TD1 小时前
Micrometer 系列【28】Spring Boot Actuator | 其他指标速览
java·spring boot·云原生
FENRON1 小时前
艺术涂料品牌怎么选?从五个维度拆解筛选逻辑
经验分享·笔记·其他
meilindehuzi_a1 小时前
深入理解 Linux 进程地址空间:从虚拟内存、页表映射到 fork 写时拷贝与 VMA 管理
java·linux·服务器
W_chuanqi1 小时前
VSCode + Claude Code + DeepSeek:打造 AI 编程神器
ide·vscode·编辑器·ai编程
莫得感情 o1 小时前
设计模式 13 · 桥接模式
java·设计模式·桥接模式
吠品1 小时前
Java中实现拓扑排序的两种方式:Kahn算法和DFS
java·数据库·notepad++
TunerT_TQ2 小时前
企业智能体工程体系v1.1|企业智能体工程卷 · 第5期· 数据飞轮——用观察—分析—计划—执行持续改进
java·运维·网络·#agent工程化·#企业智能体·#多智能体系统·#数据飞轮
csdn_aspnet2 小时前
在 Visual Studio Code 中安装使用 Github Copilot
ide·vscode·github·copilot