zoukankan      html  css  js  c++  java
  • 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();
                    }
                }
            }
    
    
    
        }

  • 相关阅读:
    Android,资料分享(2015 版)
    Http请求与响应
    SpringMVC + Spring 3.2.14 + Hibernate 3.6.10 集成详解
    ORA-14402: 更新分区关键字列将导致分区的更改
    Android Service的生命周期
    Android Service基础
    Android Intent 基本使用及对象构成
    Sublime Text3 个人使用心得
    深入了解line-height
    overflow之锚点技术实现选项卡
  • 原文地址:https://www.cnblogs.com/guosai1500581464/p/13040608.html
Copyright © 2011-2022 走看看