目录
[📕 引言](#📕 引言)
[🌴 数据流的概念](#🌴 数据流的概念)
[🚩 数据流分类](#🚩 数据流分类)
[🌳 字节流的读写](#🌳 字节流的读写)
[🚩 InputStream(从文件中读取字节内容)](#🚩 InputStream(从文件中读取字节内容))
[🚩 OutputStream(向文件中写内容)](#🚩 OutputStream(向文件中写内容))
[🎄 字符流的读写](#🎄 字符流的读写)
[🚩 Reader (读操作)](#🚩 Reader (读操作))
[🚩 Writer(写操作)](#🚩 Writer(写操作))
[⚽ 扩展](#⚽ 扩展)
[😎 小程序练习](#😎 小程序练习)
[🏀 练习一](#🏀 练习一)
[🏀 练习二](#🏀 练习二)
[🏀 练习三](#🏀 练习三)
📕 引言
关于文件内容操作:读文件,写文件,打开文件,关闭文件。
在Java 中通过"流"(stream 流)这样的一组类,进行上述的文件内容操作
🌴 数据流的概念
数据流是一串连续不断的数据的集合,就象水管里的水流,在水管的一端一点一点地供水,而在水管的另一端看到的是一股连续不断的水流。
🚩 数据流分类
流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据。因此Java中的流分为两种:
- 字节流:数据流中最小的数据单元是字节(以字节为单位,读写数据)
使用InputStream,OutputStream(都是抽象类)用于表示字节流的输入输出的类
- 字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。(以字符为单位,读写数据)
Reader 和 Writer(都是抽象类) 用于表示字符流的类
即若是文本文件使用字符流的方式处理,是二进制文件使用字节流的方式处理
总结:
🌳 字节流的读写
首先,在路径:d:/ph 下有一个text.txt文件,文件中是"hello"这样的一个字符串。
🚩 InputStream(从文件中读取字节内容)
该类提供的方法有以下几种
代码:发现我们是不能直接实例化InputStream
进入InputStream源码:他是一个抽象类,顾名思义不能实例化,所以得使用他的子类(标准库已经实现)。
注意:InputStream 只是一个抽象类,要使用还需要具体的实现类。关于 InputStream 的实现类有很多,基本可以认为不同的输入设备都可以对应一个 InputStream 类,我们现在只关心从文件中读取,所以使用FileInputStream
FileInputStream 的 构造方法:
我们在使用该实例化对对象进行操作时我们该可以分为以下几步
-
打开文件
-
进行读写操作
-
关闭文件
代码示例:
打开文件:
读取文件:
这里有三个版本的read,我们来一一分析
- 版本一:未带参数
代码:
输出一: 输出二:
- 版本二:带一个参数 baty[]
代码:
注意:while循环是防止文件很大,超过1024kb,需要搭配循环读取若干次
问题:上述两个 read() 和 read(batys) 哪个效率更高?
- 版本三:
关闭文件:
注意:
为什么要关闭文件?
上述代码好像没有写关闭文件,感觉也没有什么事啊,程序也没有报错,没有异常啊。
如果你没有关闭文件,大部分情况,你可能感知不到,但是一旦真的遇到问题,那么就是大事~~ "定时炸弹"! ! !
代码:
如果我们把 close 加到此处是有问题的,若在 close 前面出现return或者throws异常,这时此时close就执行不到!
使用 fianlly :
这就确保无论是return还是异常都可以被执行到了。
优雅一点:
但是呢这个代码看起来很麻烦,把他换种方式写
🚩 OutputStream(向文件中写内容)
当前路径下的text.txt文本文档中有一个"hello"字符串。
该类的方法有:
OutputStream 同样只是一个抽象类,要使用还需要具体的实现类。我们现在还是只关心写入文件中,所以使用 FileOutputStream,构造方法与上述FileInputStream构造方法一样的,与实现都是一样的,这里就不做过多诠释
代码注意事项:
- 版本一:
代码:
运行之后查看该文档内容:此处写的这几个数字就是abcde的ASCII码值
我们还发现按照写方法打开文件的时候,会把文件原有内容清空掉,不是write清空的,而是打开操作清空的
代码:
程序运行之后:
默认的方式打开,会清空。我们也可以使用"追加写"方式打开,就不会清空。
当前文档为空,往文档写一个字符串
代码:
程序运行一次后: 程序在运行两次之后:
🎄 字符流的读写
字符流的操作比字节流操作更加简单,而且方法类似,下面只是简单展示一下基本用法。不做过多赘述
🚩 Reader (读操作)
将该路径的文档内容改为一下字符。
这里是需要实例化一个 FileReader进行操作,可使用的方法参考字节流
代码:和上述讲的差不多,此处有四个版本,主要关注前两个
- 版本一:
运行之后:
注意:
🚩 Writer(写操作)
还是该文档路径下:
此处有5个版本,优先考虑使用版本二(String)。
代码示例:
运行之后:
除了上诉谈到的这8个类,流体系中还要很多很多的其他类,通过Java文档查看即可。
⚽ 扩展
注意:使用输入流对象的时候,还可以搭配 Scanner 使用
进入 in 的源码:正式 InputStream
😎 小程序练习
🏀 练习一
扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件。
也就是说给定路径,给定查询词,在路径中查找文件名中包含的查询词文件。
分析:由于操作系统在组织目录的时候,是按照树形结构来组织的,一个目录下可能会包含很多个子目录,也可能会包含很多个普通文件,这时候就需要遍历当前路目录中所有的内容,如果是普通文件,直接判断它是否包含了查询词,如果是目录文件,就需要递归再去子目录中进行搜索。
当前路径下有一个文档:
代码:
测试:
🏀 练习二
复制一个文件
该路径下有一个txt文档
代码:
运行: 当前路径下的文档:
代码细节:
🏀 练习三
输入一个路径,在输入一个查询词,搜索这个路径中文件内容,包含这个查询词这里的文件。把整个文件都读出来,然后进行查找。
在当前路径下,文档内容为"hello world"
代码:
注意,此代码效率非常低,如果当前搜索的文件很多,就容易 G~~
测试:
总结: