本文章来自于本人个人博客:java nio 通道(一)
通道用于在字节缓冲区和位于通道另一侧的实体(通常是一个文件或套接字)之间有效的传输数据。
在学习channel以前,先来观察一下channel的家族吧:
一,打开通道
通道分为File I/O和Stream I/O,对应的类分别为FileChannel和 SocketChannel,ServerSocketChannel, DatagramChannel。通道可以用多种方式创建,但是一个FileChannel对象却只能通过在一个打开的RandomAccessFile,FileInputStream和FileOutputStream对象上调用getChannel()方法来获取。
SocketChannel sc = SocketChannel.open(); sc.connect(new InetSocketAddress("localhost",port)); ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.socket().bind(new InetSocketAddress("localhost",port)); DatagramChannel dc = Datagram.open(); RandomAccessFile raf = new RandomAccessFile("filepath","r"); FileChannel fc = raf.getChannel();
在使用IO流创建文件通道时,如果RandomAccessFile创建的时候是只读,则通道也是只读,如果设置的是写或者读写模式,则可修改数据。因此,通过FileChannel得到的ByteBuffer也将随着只读而只读,读写而读写。
二,矢量I/O
矢量I/O即Scatter/Gather,scatter的功能是将一个大缓冲区的数据一次性读入几个小的缓冲区中,而gather的功能是将几个小缓冲区的数据一次性读入一个大的缓冲区中,然后沿着通道发送出去。Scatter/Gather应该使用直接的ByteBuffer以从本地I/O获取最大性能优势。
ByteBuffer header = ByteBuffer.allocateDirect(10); ByteBuffer body = ByteBuffer.allocateDirect(80); ByteBuffer[] buffers = {header, body}; int bytesRead = channel.read(buffers);
here is a simple example:
通道用于在字节缓冲区和位于通道另一侧的实体(通常是一个文件或套接字)之间有效的传输数据。 在学习channel以前,先来观察一下channel的家族吧: 一,打开通道 通道分为File I/O和Stream I/O,对应的类分别为FileChannel和 SocketChannel,ServerSocketChannel, DatagramChannel。通道可以用多种方式创建,但是一个FileChannel对象却只能通过在一个打开的RandomAccessFile,FileInputStream和FileOutputStream对象上调用getChannel()方法来获取。SocketChannel sc = SocketChannel.open(); sc.connect(new InetSocketAddress("localhost",port)); ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.socket().bind(new InetSocketAddress("localhost",port)); DatagramChannel dc = Datagram.open(); RandomAccessFile raf = new RandomAccessFile("filepath","r"); FileChannel fc = raf.getChannel();在使用IO流创建文件通道时,如果RandomAccessFile创建的时候是只读,则通道也是只读,如果设置的是写或者读写模式,则可修改数据。因此,通过FileChannel得到的ByteBuffer也将随着只读而只读,读写而读写。
二,矢量I/O
矢量I/O即Scatter/Gather,scatter的功能是将一个大缓冲区的数据一次性读入几个小的缓冲区中,而gather的功能是将几个小缓冲区的数据一次性读入一个大的缓冲区中,然后沿着通道发送出去。Scatter/Gather应该使用直接的ByteBuffer以从本地I/O获取最大性能优势。
ByteBuffer header = ByteBuffer.allocateDirect(10); ByteBuffer body = ByteBuffer.allocateDirect(80); ByteBuffer[] buffers = {header, body}; int bytesRead = channel.read(buffers);here is a simple example:
package com; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.GatheringByteChannel; import java.nio.channels.ScatteringByteChannel; public class TestByteOrder { /** * 功能: * 作者: jiangfuqiang * 创建日期:2014-8-3 * 修改者: mender * 修改日期: modifydate * @param args * @throws IOException */ public static void main(String[] args) throws IOException { File file = new File("/Users/jiang/Desktop/3.txt"); if(!file.exists()) { file.createNewFile(); } FileOutputStream fos = new FileOutputStream(file); GatheringByteChannel gbc = fos.getChannel(); ByteBuffer buffer1 = ByteBuffer.allocateDirect(10); buffer1.put((byte)‘j‘); buffer1.put((byte)‘i‘); buffer1.put((byte)‘a‘); buffer1.put((byte)‘n‘); buffer1.put((byte)‘g‘); buffer1.put((byte)‘j‘); buffer1.put((byte)‘i‘); buffer1.put((byte)‘a‘); buffer1.put((byte)‘n‘); buffer1.put((byte)‘\n‘); ByteBuffer buffer2 = ByteBuffer.allocateDirect(20); buffer2.put((byte)‘j‘); buffer2.put((byte)‘i‘); buffer2.put((byte)‘a‘); buffer2.put((byte)‘n‘); buffer2.put((byte)‘g‘); buffer2.put((byte)‘f‘); buffer2.put((byte)‘u‘); buffer2.put((byte)‘h‘); buffer2.put((byte)‘x‘); buffer2.put((byte)‘n‘); buffer2.put((byte)‘j‘); buffer2.put((byte)‘i‘); buffer2.put((byte)‘a‘); buffer2.put((byte)‘n‘); buffer2.put((byte)‘g‘); buffer2.put((byte)‘f‘); buffer2.put((byte)‘u‘); buffer2.put((byte)‘h‘); buffer2.put((byte)‘x‘); buffer2.put((byte)‘\n‘); ByteBuffer buffer3 = ByteBuffer.allocateDirect(30); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); buffer3.put((byte)‘j‘); // buffer3.put((byte)‘j‘); // buffer3.put((byte)‘j‘); //一定要记得在写入以前调用flip方法 buffer1.flip(); buffer2.flip(); buffer3.flip(); ByteBuffer[] buffers = {buffer1,buffer2,buffer3}; while(gbc.write(buffers) > 0) { } gbc.close(); FileInputStream fis = new FileInputStream(file); ScatteringByteChannel sbc = fis.getChannel(); ByteBuffer b1 = ByteBuffer.allocateDirect(10); ByteBuffer b2 = ByteBuffer.allocateDirect(20); ByteBuffer b3 = ByteBuffer.allocateDirect(30); ByteBuffer[] bs = {b1,b2,b3}; sbc.read(bs); for(ByteBuffer bb : bs) { bb.flip(); //注意,这个数组的初始化一定要放在flip()方法的后面,不然会将所读取的数据截断 byte[] data = new byte[bb.remaining()]; while(bb.hasRemaining()) { //System.out.println(bb.get()); bb.get(data); if(data.length > 0) { System.out.print(data.length + " data=" + new String(data)); } data = new byte[bb.remaining()]; } bb.clear(); } } }下一篇我们将一起来学习文件通道
下一篇我们将一起来学习文件通道
java nio 通道(一)