FileChannel是用于读取、写入、映射和操作文件的通道。
方法分类
简介(注释译文)
文件通道是连接到文件的 SeekableByteChannel
。
它在其文件中有一个当前位置,可以查询和修改。
文件本身包含一个可变长度的字节序列,可以读取和写入,并且可以查询其当前大小。
当写入的字节超过其当前大小时,文件的大小会增加;文件被 truncated
时,其大小会减小。
文件还可以具有一些相关联的元数据,例如访问权限、内容类型和上次修改时间;这个类没有定义元数据访问的方法。
除了熟悉的字节通道的读、写和关闭操作之外,此类还定义了以下特定于文件的操作:
可以以不影响通道当前位置的方式在文件中的绝对位置读取或写入字节。
文件的一个区域可以直接映射到存储器中;对于大型文件,这通常比调用通常的读或写方法更有效。
对文件所做的更新可能会被强制发送到底层存储设备,以确保在系统崩溃时不会丢失数据。
字节可以从文件传输到其他通道,反之亦然,这种方式可以被许多操作系统优化为直接进出文件系统缓存的非常快速的传输。
文件的某个区域可能被锁定,以防其他程序访问。
多个并发线程可以安全使用文件通道。
根据Channel接口的规定,可以随时调用close方法。
在任何给定时间,只有一项涉及通道位置或可以更改其文件大小的操作正在进行;
在第一个操作仍在进行时尝试启动第二个此类操作将阻塞,直到第一个操作完成。其他操作,特别是那些后去明确位置的,可以同时进行;事实上它们是否这样做取决于底层实现,因此没有具体说明。
此类实例提供的文件视图保证与同一程序中其他实例提供的同一文件的其他视图一致。
然而,由于底层操作系统执行的缓存和网络文件系统协议引起的延迟,此类实例提供的视图可能与其他并发运行程序看到的视图一致,也可能不一致。
无论这些其他程序是用什么语言编写的,无论它们是在同一台机器上还是在其他机器上运行,这都是正确的。
任何此类不一致的确切性质都取决于系统,因此不明确。
通过调用该类定义的任何一个 open
方法来创建文件通道。
也可以通过调用现有 FileInputStream
、FileOutputStreet
或 RandomAccessFile
对象的 getChannel
方法从该对象获取文件通道,该方法返回连接到同一底层文件的文件通道。
如果文件通道是从现有的流或随机访问文件中获得的,则文件通道的状态与 getChannel
方法返回通道的对象的状态密切相关。
无论是显式还是通过读取或写入字节来更改通道的位置,都会更改原始对象的文件位置,反之亦然。
通过文件通道更改文件的长度将更改通过原始对象看到的长度,反之亦然。
通过写入字节更改文件内容将更改原始对象看到的内容,反之亦然。
不同的形式指向该类,需要指明实例的打开是为了: 读、写,还是读写。
通过FileInputStream实例的getChannel方法获得的通道将打开以供读取。
通过FileOutputStream实例的getChannel方法获得的通道将打开以供写入。
通过RandomAccessFile实例的getChannel方法获得的通道,如果使用模式“r”创建实例,那么是读模式,如果使用“rw”创建实例则打开以供读写
打开用于写入的文件通道可能处于追加模式
例如,如果它是从通过调用 FileOutputStream(file,boolean)
构造函数并为第二个参数传递 true
而创建的文件输出流中获得的。
在这种模式下,每次调用相对写入操作都首先将位置推进到文件的末尾,然后写入请求的数据。
位置的推进和数据的写入是否是在单个原子操作中完成的,这取决于系统,因此没有具体说明。
创建打开
open
方法用于创建,需要关注 OpenOption
这个通常是可以多个一起使用的。
public enum StandardOpenOption implements OpenOption {
/**
* 以读的方式连接文件。
*/
READ,
/**
* 以写的方式连接文件。
*/
WRITE,
/**
* 以追加的方式连接文件,不会覆盖文件原本内容,在后面追加。
*/
APPEND,
/**
* 如果文件存在并且以WRITE的方式连接时就会把文件内容清空,文件设置为0字节大小。
* 如果文件只以READ连接 时,该选项会被忽略。
*/
TRUNCATE_EXISTING,
/**
* 创建一个文件,如果文件已存在,就打开文件连接。与CREATE_NEW同时存在时该选项会被忽略。
*/
CREATE,
/**
* 创建一个文件,如果文件已存在,如果已经存在会抛异常。
*/
CREATE_NEW,
/**
* 通道关闭时删除文件
*/
DELETE_ON_CLOSE,
/**
* 创建稀疏文件,与CREATE_NEW选项配合使用。
*/
SPARSE,
/**
* 要求每次写入要把内容和元数据刷到存储设备上。
*/
SYNC,
/**
* 要求每次写入那内容刷到存储设备上
*/
DSYNC;
}
比如想要如果文件不存在,就创建,然后如果存在就追加
可以使用 CREATE
APPEND
大小位置
读写
针对于Channel的读写方法,需要确认源,源就是Channel。
如果是读,那么是从Channel中读取到Buffer;
如果是写,那么是将Buffer中的数据,写入到Channel;