1.什么是通道:
有java.nio.channels包定义的。Channel表示IO源与目标打开的连接。
Channel类似于传统的“流”。只不过Channel本身不能访问数据,Channel只能与Buffer交互。
2.那么通道是怎么发展过来的:
在最开始的时候程序等IO操作就是通过系统的IO接口与CPU进行交互,从而进行读写的操作,但是这样对于CPU来说负担太大,大大降低了CPU的利用率,所以后来又发展出了DMA的总线对IO进行处理,但是在进行IO处理的时候它还需要先得到CPU的允许,并且在高IO的时候,它还会出现总线冲突的问题,所以最后出现了通道机制。通道自身就拥有一个处理机,它是专门用来处理IO操作的。
3.代码示例:
/*
*一、通道的主要实现类:
* java.nio.Channel 接口:
* |--FileChannel
* |--SocketChannel
* |--ServerSocketChannel
* |--DatagramChannel
*
*二、获取通道
*1.Java 针对支持通道的类提供了 getChannel() 方法
* 本地IO
* FileInputStream/FileOutputStream
* RandomAccessFile
*
* 网络IO
* Socket
* ServerSocket
* DatagramSocket
*
*2.在 JDK 1.7 中的 NIO.2 针对各个通道提供了静态方法 open()
*3.在 JDK 1.7 中的 NIO.2 的Files工具类的方法 newByteChannel()
*
*三、通道之间的数据传输
*transferFrom()
*transferTo()
*/
public class TestChannel{
//3.通道之间的数据传输(直接缓冲区的方式)
@Test
public void test2(){
FileChannel inChannel =
FileChannel.open(Paths.get("1.jpg"),StandardOpenOption.READ);
FileChannel outChannel =
FileChannel.open(Paths.get("3.jpg"),StandardOpenOption.WRITE,
StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
//inChannel.transferTo(0.inChannel.size(),outChannel);
outChannel.transferFrom(inChannel,0,inChannel.size());
inChannel.close();
outChannel.close();
}
//2.使用直接缓冲区完成文件的复制(内存映射文件)
//在使用这种方法的问题是不稳定,需要在效率有显著提升的情况下再去使用
@Test
public void test2(){
FileChannel inChannel =
FileChannel.open(Paths.get("1.jpg"),StandardOpenOption.READ);
FileChannel outChannel =
FileChannel.open(Paths.get("3.jpg"),StandardOpenOption.WRITE,
StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
//内存映射文件
MappedByteBuffer inMappedBuf =
outChannel.map(MapMode.READ_ONLY,0,inChannel.size());
MappedByteBuffer outMappedBuf =
outChannel.map(MapMode.READ_WRITE,0,inChannel.size());
//直接对缓冲区进行数据的读写操作
byte[] dst = new byte[inMappeedBuf.limit()];
inMappedBuf.get(dsf);
outMappedBuf.put(def);
inChannel.close();
outChannel.close();
}
//1.利用通道完成文件的复制(非直接缓冲区)
@Test
public void test1(){
FileInputStream fis = new FileInputStream("1.jpg");
FileOutputStream fos = new FileOutputStream("2.jpg");
//获得通道
FileChannel inChannel = fis.getChannel();
FileChannel outChannel = fos.getChannel();
//分配指定大小的缓冲区
ByteBuffer buf = ByteBuffer.allocate(1024);
//将通道的数据存入缓冲区中
while(inChannel.read(buf) != -1){
//切换读取数据的模式
buf.flip();
//将缓冲区中的数据写入通道
outChannel.write(buf);
//清空缓冲区
buf.clear();
}
outChannel.close();
inChannel.close();
fos.close();
fis.close();
}
}