Java NIO中最重要的通道的实现:
FileChannel :从文件中读写数据
DatagramChannel :通过UDP读写网络中的数据
SocketChannel :通过TCP读写网络中的数据
ServerSocketChannel :监听TCP连接,对每一个新进来的连接都会创建一个ScoketChannel
FileChannel 文件通道,通过通道读写文件,无法设置为非阻塞模式
在使用FileChannel之前,必须先打开它,需要通过使用inputStream,outputStream或者RandomAccessFile来获取实例
File file = new File("C:\\Users\\Administrator\\Desktop\\editChargeInfo.jsp");
FileChannel fileChannel = new RandomAccessFile(file, "rw").getChannel();
FileChannel -> buffer ,调用信道的read方法,底层会调用缓冲区的put方法
//从fileChannel中读取数据
ByteBuffer buffer = ByteBuffer.allocate((int)file.length());
buffer.clear();
int read = fileChannel.read(buffer);
FileChannnel <- buffer,调用信道的write方法,底层调用缓冲区的get方法
//向FileChannel中写数据
String data = "It is a FileChannel,now write some data to Channnel at its end";
byte[] b = data.getBytes();
buffer.clear();
buffer.put(b);
buffer.flip();
while(buffer.hasRemaining()){
fileChannel.write(buffer);
}
使用完FileChannel后,必须将它关闭,调用close方法
position()/position(long pos)方法
使用position()方法获取FileChannel的当前位置,调用position(long pos) 方法设置FileChannel的当前位置
long position = fileChannel.position();
fileChannel.position(position+123);//设置FileChannel的位置
如果将位置设置的文件结束符之后,然后试图从文件通道中读取数据,读方法将返回-1,文件结束标识
如果将位置设置在文件结束之后,然后向通道中写数据,文件将撑大当前位置并写入数据,可能导致文件空洞,磁盘上物理文件中写入的数据间有空隙
size()方法
返回文件通道关联文件的字节数
截取文件的长度,截取的是文件的前多上字节的长度内容
force(Boolean b)
force将通道内未写入到磁盘的数据强制写入到磁盘上。
出于性能方面的考虑,操作系统会将数据缓存在内存中,所以无法保证写入到FileChannel里的数据一定会即时写到磁盘上。要保证这一点,需要调用force()方法。
force()方法有一个boolean类型的参数,指明是否同时将文件元数据(权限信息等)写到磁盘上。
通道间的数据传输
java NIO中两个通道中如果有一个是FileChannel,就可以将数据从一个Channel传输到另一个Channel
transferFrom()
destTarge.transferFrom( src, position, count)
destTarge: FileChannel
src:channel
position:开始位置
count:传输的总字节数
FileChannel的transferFrom()方法可以将数据从源通道就是方法中的通道数据传输到FileChannel中
File file = new File("C:\\Users\\Administrator\\Desktop\\editChargeInfo.jsp");
srcChannel = new RandomAccessFile(file, "rw").getChannel();
File filet = new File("C:\\Users\\Administrator\\Desktop\\t.jsp");
targetChannel = new RandomAccessFile(filet, "rw").getChannel();
targetChannel.transferFrom(srcChannel, 0, srcChannel.size());
targetChannel.force(false);
注意到:
如果src是socketchannel,只会传输准备好的字节,不一定传输count个字节
transferTo()
FileChannel.transferTo(int position,int count, Channel target)
从文件通道FileChannel传输数据到Channel中,两者有点类似,只不过反过来而已
如果target是socketchannel,一直传输数据直到buffer填满
srcChannel = new RandomAccessFile(file, "rw").getChannel();
File filet = new File("C:\\Users\\Administrator\\Desktop\\test.jsp");
targetChannel = new RandomAccessFile(filet, "rw").getChannel();
srcChannel.transferTo(0, srcChannel.size(), targetChannel);
targetChannel.force(false);