通道Channel
基本介绍:
-
NIO通道类似于流,但有些区别
a. 通道可以同事进行读写,而流只能读或者写
b. 通道可以实现异步读写数据
c. 通道可以从缓冲区读数据,也可以写数据到缓冲区
-
BIO中的stream 是单向的,例如FileInputStream对象只能进行读取数据的操作,而NIOs双向的 ,可以读操作,也可以写操作
-
Channel在NIO中是一个接口
public interface Channel extends Closeable {}
-
常用的Channel类有
- FileChannel
- ServerSocketChannel
- SocketChannel
- DatagramChannel
-
FileChannel用于文件的数据读写;DatagramChannel用于UDP的数据读写;ServerSocketChannel用于TCP数据读写
-
FileChannel类
- FileChannel主要用于对本地文件进行IO操作,常用方法有
- public int read(ByteBuffer dst) ,从通道读取数据并放到缓冲区中public int write(ByteBuffer src),把缓冲区的数据写到通道中
- public long transferFrom(ReadableByteChannel src, long position, long count),从目标通道中复制数据到当前通道public long
- transferTo(long position , long count, WritableByteChannel target),把数据从当前通道复制给目标通道
读入写出案例
目标:将文件2的内容读入到文件1中去
// 创建两个 通道,一个缓冲区,将2读入的内容写出到1里面
FileOutputStream outputStream = new FileOutputStream("d://1.txt");
FileInputStream inputStream = new FileInputStream("d://2.txt");
FileChannel channel1 = outputStream.getChannel();
FileChannel channel = inputStream.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while (true) {
// 思路:buffer 读入1.txt channel通道,写出到channel1通道
byteBuffer.clear();
int read = channel.read(byteBuffer);
System.out.println(new String(byteBuffer.array()));
if(read==-1) { // 读入结束
break;
}
// 写出到channel1
//一定要记得读入写出进行转换阿
byteBuffer.flip();
channel1.write(byteBuffer);
}
// 最后进行关流操作
outputStream.close();
inputStream.close();
图片的拷贝
- transferFrom的使用
// 图片拷贝
FileInputStream inputStream = new FileInputStream("d://a.png");
FileOutputStream outputStream = new FileOutputStream("d://b.png");
// 创建 对应的通道
FileChannel resoursePath = inputStream.getChannel();
FileChannel destPath = outputStream.getChannel();
destPath.transferFrom(resoursePath, 0, resoursePath.size());
// 关闭对应的流和通道
inputStream.close();
outputStream.close();
resoursePath.close();
destPath.close();
关于Buffer与Channel的注意事项与细节
- ByteBuffer支持类型化的put和get,put放入的是什么数据类型,get就应该对应什么数据取出,否则报BufferUnderflowException异常
- 可以将一个普通Buffer转化成只读Buffer
- NIO提高mappedBuffer,可以让文件直接在内存(堆外的内存)中进行修改,而如何同步到文件由NIO来完成
- NIO还支持通过多个Buffer(Buffer数组)来完成读写操作,即SCattering 和Gathering