X Tutup
Skip to content

Latest commit

 

History

History
101 lines (60 loc) · 3.55 KB

File metadata and controls

101 lines (60 loc) · 3.55 KB

#08.Java NIO FileChannel

FileChannel是一个用于连接文件的通道类。使用FileChannel你可以读取文件的数据或往文件里写入数据。使用FileChannel可以代替标准的Java IO API中对文件的操作。

FileChannel不能设置为非阻塞模式,它总是以阻塞模式运行。

##打开FileChannel(Opening a FileChannel)

当需要使用FileChannel时,你需要首先打开一个FileChannel,但你不能直接打开。你必须要通过InputStream,OutputStreamRandomAccessFile来获得一个FileChannel实例。如下面这个例子:

RandomAccessFile aFile     = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel      inChannel = aFile.getChannel();

##从FileChannel中读取数据(Reading Data from a FileChannel)

FileChannel中读取数据,可以调用多个重载的read()方法。

ByteBuffer buf = ByteBuffer.allocate(48);

int bytesRead = inChannel.read(buf);

当**缓冲区(Buffer)**分配之后,数据从FileChannel中读取到缓冲区。

FileChannel.read()被调用后,这个方法会从FileChannel中读取数据到缓冲区。read()方法会返回一个int值,这个值代表了写入缓冲区的字节数。如果返回值是-1,则没有数据被读取。

##往FileChannel中写入数据(Writing Data to a FileChannel)

FileChannel中写数据用的是FileChannel.write()方法,这个方法也会带有个Buffer类型参数。

String newData = "New String to write to file..." + System.currentTimeMillis();

ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());

buf.flip();

while(buf.hasRemaining()) {
    channel.write(buf);
}

注意这里的FileChannel.write()方法是在while循环里面进行的。我们并不知道有多少数据要写入到FileChannel中,因此我们需要重复地调用write()方法直到缓冲区中没有数据可写。

##关闭FileChannel(Closing a FileChannel)

当使用完FileChannel后,必须要关闭它:

channel.close();    

##FileChannel Position

当从FileChannel读取数据往其中写人数据时,我们需要要指定特定的位置。你可以通过调用position()方法来获得FileChannel当前的位置。

你也可以通过position(long pos)方法来设置FileChannel的位置。

long pos channel.position();

channel.position(pos +123);

如果你将position设置到文件的末尾之后,当你再对FileChannel进行读取时,将会返回-1,表明读取到了文件末尾。

如果你将position设置到文件的末尾之后,让你往FileChannel写入数据时,文件就会自动拓展到position所指定的位置并写入数据。这会导致文件空洞(File Hole)

##FileChannel Size

FileChannel.size()方法会返回通道所连接的文件的大小。

long fileSize = channel.size();    

##FileChannel Truncate

你可以通过FileChannel.truncate()方法对通道所关联的文件进行截取:

channel.truncate(1024);

##FileChannel Force

FileChannel.force()方法会将所有通道中的数据刷新到磁盘中。操作系统会处于性能考虑将数据缓存到内存中,所以你不能保证写入到通道中的数据会立刻同步到磁盘,因此你可以通过force()方法将通道中的数据刷新到物理磁盘。

FileChannel.forece()方法带有一个布尔类型的参数,这个参数用于指定文件的**元数据(meta data)**是否也需要刷新到物理磁盘。

channel.force(true);
X Tutup