NIO 学习(三) channel(主要介绍channel----FileChannel详解--通道间的信息传输)

Channel实现

Java NIO中最重要的通道的实现:

FileChannel :从文件中读写数据

DatagramChannel :通过UDP读写网络中的数据

SocketChannel  :通过TCP读写网络中的数据

ServerSocketChannel :监听TCP连接,对每一个新进来的连接都会创建一个ScoketChannel


FileChannel

FileChannel 文件通道,通过通道读写文件,无法设置为非阻塞模式

打开FileChannel

在使用FileChannel之前,必须先打开它,需要通过使用inputStream,outputStream或者RandomAccessFile来获取实例

File file = new File("C:\\Users\\Administrator\\Desktop\\editChargeInfo.jsp");
FileChannel fileChannel = new RandomAccessFile(file, "rw").getChannel();

从FileChannel中读取数据

FileChannel -> buffer ,调用信道的read方法,底层会调用缓冲区的put方法

//从fileChannel中读取数据
ByteBuffer buffer = ByteBuffer.allocate((int)file.length());
buffer.clear();
int read = fileChannel.read(buffer);

首先,创建一个buffer,从FileChannel中读取到的数据,将读到buffer缓冲区中,返回的数值,表示读取到缓冲区的字节数,如果返回-1,表示到了文件末尾

向FileChannel中写数据

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

使用完FileChannel后,必须将它关闭,调用close方法


FileChannel的其他方法

position()/position(long pos)方法

使用position()方法获取FileChannel的当前位置,调用position(long pos) 方法设置FileChannel的当前位置

long position = fileChannel.position();
fileChannel.position(position+123);//设置FileChannel的位置

如果将位置设置的文件结束符之后,然后试图从文件通道中读取数据,读方法将返回-1,文件结束标识

如果将位置设置在文件结束之后,然后向通道中写数据,文件将撑大当前位置并写入数据,可能导致文件空洞,磁盘上物理文件中写入的数据间有空隙

size()方法

返回文件通道关联文件的字节数

truncate(long 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);

可以使用fileChannel优化大文件的复制工作,效率很高



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值