JavaNio之ByteBuffer

Posted 七月在野,八月在宇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaNio之ByteBuffer相关的知识,希望对你有一定的参考价值。

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();
                }
            }
        }



    }

 

以上是关于JavaNio之ByteBuffer的主要内容,如果未能解决你的问题,请参考以下文章

Mina 组件介绍之 IoBuffer

Java NIO ByteBuffer:在读取完整消息之前先读取消息大小

JDK源码阅读:ByteBuffer

JavaNIO缓冲区

JDK 源码阅读 :ByteBuffer

Java NIO 中的 ByteBuffer 和 CharBuffer 有啥区别?