java.io - 目录 | ||
---|---|---|
标准设备输入/输出 | 标准设备输入/输出:System | |
控制台读写类:Console | ||
文件基本处理 | 文件操作类:File | |
文件搜索类:FileFilter、FilenameFilter | ||
文件任意读写类:RandomAccessFile | ||
输入/输出流 | 输入/输出流 - 分类 | |
输入/输出流 - 实现类 | ||
序列化/反序列化 |
一、使用场景
📌 RandomAccessFile 既可以读取文件内容,也可以向文件输出数据,是一个更接近于操作系统API的封装类。
- 与普通的输入/输出流不同的是, 它支持“随机访问”的方式,程序可以直接跳转到文件的任意地方来读写数据。(与InputStream、Reader需要依次向后读取相区分)
- 它将文件内容存储在一个大型byte数组中。它存在着指向该隐含byte数组的光标或索引,称为文件指针,该指针位置可以通过seek方法设置
使用场景:
%%{ init: { 'themeVariables': { 'fontSize': '13px' } } }%% graph LR T(["RandomAccessFile 的使用场景"]):::p T --> A("仅访问文件部分内容"):::lp T --> B("向已存在的文件后追加内容"):::lp classDef p fill:#ddaebd classDef b fill:#aab7d2 classDef g fill:#9ac5bb classDef lp fill:#f4e4e9 classDef lb fill:#d9dfeb classDef lg fill:#ddebe6 classDef info fill:#f6f6f7,color:#737379,stroke-dasharray: 3 3, stroke-width: 2px
- 只访问文件部分内容,而不是把文件从头读到尾,使用RandomAccessFile更好。
- 向已存在的文件后追加内容:与OutputStream、Writer等输出流不同的是,RandomAccessFile允许自由定位文件记录指针,所以RandomAccessFile可以不从开始的地方开始输出,所以RandomAccessFile可以向已存在的文件后追加内容。
二、方法
① 构造方法
方法 | 说明 |
---|---|
RandomAccessFile(File file, String mode) | 使用File参数来指定文件本身(打开文件) |
RandomAccessFile(String name, String mode) | 使用String参数来指定文件名(打开文件) |
RandomAccessFile的4种访问模式:
参数值 说明 r 以只读方式打开指定文件。若试图对该RamdomAceessFile执行写入方法,都将执行IOException异常 rw 以读、写方式打开指定文件。如果该文件尚不存在,则尝试创建该文件。 rws 以读、写方式打开指定文件。相对于”rw”模式,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。 rwd 以读、写方式打开指定文件。相对于”rw”模式,还要求对文件内容的每个更新都同步写入到底层存储设备。
* rwd模式可用于减少执行的I/O操作数量。
② 操作文件指针
RandomAccessFile对象的记录指针:指向当前读写的位置,各种read/write操作都会自动更新该指针(移动单位:字节)。
方法 | 说明 |
---|---|
long getFilePointer() | 返回文件记录指针的当前位置。 |
void seek(long pos) | 将文件记录指针定位到pos位置。 |
void skipBytes(int n) | 使文件指针向前移动指定的n个字节。 |
* 当程序新创建一个RandomAccessFile对象时,该对象的文件记录指针位于文件头(也就是0处),当读/写了n个字节后,文件记录指针将会向后移动n个字节。
③ 读写方法
RandomAccessFile实现了DataInput/DataOutput
接口:
* 读取:
|
* 写入:
|
三、实例
① 访问指定的中间部分数据
|
② 向指定文件后追加内容
|
③ 向指定文件、指定位置插入内容
|
四、应用
多线程断点的网络下载工具(如FlashGet等)就可通过RandomAccessFile类来实现:
%%{ init: { 'themeVariables': { 'fontSize': '13px' } } }%% graph LR subgraph "[ 多线程断点的网络下载工具 ]" A[["与被下载文件大
小相同的空文件"]]:::lp B[["记录文件指针
的位置文件"]]:::lb end net("网络数据"):::info -.->|"写入"| A A --> |"每写一些数据:
记下文件指针位置"|B B -.-> |"断网后再次下载:
根据记录的位置
继续向下写数据"|A classDef p fill:#ddaebd classDef b fill:#aab7d2 classDef g fill:#9ac5bb classDef lp fill:#f4e4e9 classDef lb fill:#d9dfeb classDef lg fill:#ddebe6 classDef info fill:#f6f6f7,stroke-dasharray: 3 3, stroke-width: 2px, stroke: #676666下载工具用多条线程启动输入流来读取网络数据,并使用RandomAccessFile将从网络上读取的数据写入前面建立的空文件中,每写一些数据后,记录文件指针的文件就分别记下每个RandomAccessFile当前的文件指针位置。
- end -
🔖 笔记来自: