前言:
在 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() | 获取规范化之后的绝对路径,会解析 …/、./ 这类相对符号 |
此处我们具体讲解:getabsolutepath与getcanonicalpath的区别
假设我们的文件路径为: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) | 利用文件路径构造文件输入流 |
//方式1:传入file对象
file file = new file("test.txt");
inputstream in1 = new fileinputstream(file);
//方式2:传入路径字符串
inputstream in2 = new fileinputstream("test.txt");
我们可以直接new一个fileinputstream对象也可以使用reader抽象类来实现向上转型的写法,企业常规写法:
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) | 路径形式,设置是否追加写入 |
当然我们也可以使用read和writer来实现多态,这也是日常开发中常使用的方法;
//父类引用指向子类对象
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类似,这里不过多进行讲解;
- filewriter 具备缓冲区,write 之后数据暂存内存,必须 flush () 或者 close () 才会把数据落地磁盘;
- 构造方法开启追加模式 new filewriter(“xxx.txt”,true),不会清空旧文件;
- 字节流没有直接写入字符串的重载,这是字符流的优势。
4 printwriter便捷打印输出流
filewriter属于基础字符输出流,只能够写入字符、字符数组、字符串。
如果需要写入数字、布尔值,我们需要手动拼接字符串转换:
filewriter.write(666 + "");
而printwriter 是增强型装饰字符输出流,专门用来简化文本写入,能够自动将 int、double、boolean、对象转换成字符串写入文件,适合书写日志、导出文本。
字节流与printwriter选取:
- 视频、图片、压缩包 → 使用字节流
- 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 | 关闭流,关闭前自动刷新缓冲区 |
- print() / println():
底层调用string.valueof(),自动把数字、布尔、对象转为文本。
pw.println(97) 写入文件内容为字符串97 - write(int c):
把参数当作字符编码,写入对应字符。
pw.write(97) 写入文件内容为字符a
例如;

注意事项:
- print() 就算开启自动刷新,也不会刷新缓冲区;
只有 println、printf 触发自动刷新; - 字符流带有缓冲区,忘记 flush/close,文件内容为空;
- printwriter 只是装饰流,底层依旧依赖
filewriter完成文件写入。
总结
到此这篇关于java文件io之file文件类、字节流、字符流详细讲解的文章就介绍到这了,更多相关java file文件类、字节流、字符流内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论