nio使用通道和缓冲区来进行数据的读写操作。
FileChannel 对文件进行操作
SocketChannel tcp
ServerSocketChannel tcp
DatagramChannel udp
一般来说分为下面几步:1、建立通道2、创建缓冲区3、使用通道对缓冲区进行读写操作
建立通道:对本地文件:FileChannel
直接缓冲区:使用FileInputStream 和 FileOutStream两个流进行操作,获取通道方法:getChannel()
fis = new FileInputStream("C:\Users\郭赛\Desktop\angle王鸥\鸥美人.jpg"); fos = new FileOutputStream(file); //获取通道, inchannel = fis.getChannel(); outchannel = fos.getChannel(); //开辟缓冲区 ByteBuffer buffer = ByteBuffer.allocate(1024); //将通道中的内容存到缓冲区 //inchannel.read(buffer); while(inchannel.read(buffer) != -1){ buffer.flip(); outchannel.write(buffer); buffer.clear();
非直接缓冲区:使用open()方法创建FileChannel,然后调用FileChannel.map()方法获取直接缓冲区
1 readChannel = FileChannel.open(Paths.get("C:\Users\郭赛\Desktop\1.jpg"), StandardOpenOption.READ); 2 //writeChannel = FileChannel.open(Paths.get("C:\Users\郭赛\Desktop\3.jpg"),StandardOpenOption.WRITE,StandardOpenOption.CREATE_NEW);//java.nio.channels.NonReadableChannelException
3 writeChannel = FileChannel.open(Paths.get("C:\Users\郭赛\Desktop\4.jpg"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
4 //直接获取内存映射文件
5 MappedByteBuffer inmode = readChannel.map(FileChannel.MapMode.READ_ONLY,0,readChannel.size());
6 MappedByteBuffer outmode = writeChannel.map(FileChannel.MapMode.
7 READ_WRITE,0,readChannel.size());//java.nio.channels.NonReadableChannelException因为我设定的通道只能写,缓冲区却是读写
8 byte[] bytes = new byte[inmode.limit()]; 9
10 inmode.get(bytes);//通过通道从文件读取信息到缓冲区
11 //inmode.flip();
12 outmode.put(bytes);//通过通道将缓冲区内容写到文件中
使用get(i) 和put(i,byte b)的方法也可以完成读取
1 File file = new File("C:\Users\郭赛\Desktop\1.jpg"); 2 @Test 3 public void test03(){ 4 FileChannel readChannel = null; 5 FileChannel writeChannel = null; 6 Path path = Paths.get("C:\Users\郭赛\Desktop\1.jpg");//通过字符串获取路径 7 try { 8 readChannel = FileChannel.open(path,StandardOpenOption.READ); 9 writeChannel = FileChannel.open(Paths.get("C:\Users\郭赛\Desktop\2.jpg"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE); 10 //ByteBuffer bytebuffer = ByteBuffer.allocate(1024); 11 MappedByteBuffer map = readChannel.map(FileChannel.MapMode.READ_ONLY, 0, readChannel.size()); 12 MappedByteBuffer map1 = writeChannel.map(FileChannel.MapMode.READ_WRITE, 0, readChannel.size()); 13 byte[] bytes = new byte[1024]; 14 ByteBuffer s; 15 for (int i = 0; i < readChannel.size(); i++) { 16 byte b = map.get(i); 17 map1.put(i,b); 18 } 19 20 } catch (IOException e) { 21 e.printStackTrace(); 22 }finally { 23 if(writeChannel ==null) 24 try { 25 26 writeChannel.close(); 27 } catch (IOException e) { 28 e.printStackTrace(); 29 } 30 if(readChannel == null) 31 try { 32 readChannel.close(); 33 } catch (IOException e) { 34 e.printStackTrace(); 35 } 36 } 37 38 39 }
使用writeChannel.transferFrom()方法 从读通道获取数据
还有一个是readChannel.transferTo()方法 向写通道写入数据
这个也是使用的内存直接映射文件
@Test public void test04(){ /** * */ FileChannel readChannel = null; FileChannel writeChannel = null; Path path = Paths.get("C:\Users\郭赛\Desktop\1.jpg");//通过字符串获取路径 try { readChannel = FileChannel.open(path,StandardOpenOption.READ); writeChannel = FileChannel.open(Paths.get("C:\Users\郭赛\Desktop\9.jpg"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE); writeChannel.transferFrom(readChannel,0,readChannel.size()); } catch (IOException e) { e.printStackTrace(); }finally { if(writeChannel == null) { try { writeChannel.close(); } catch (IOException e) { e.printStackTrace(); } } if(readChannel == null) { try { readChannel.close(); } catch (IOException e) { e.printStackTrace(); } } } }