JavaNIO读取文件


一、JavaNIO读取文件

1、使用缓冲区,非直接缓冲区读写文件

 @Test
 public void test3() {
         FileInputStream fis = null;
         FileOutputStream fos = null;
         FileChannel fisChannel = null;
         FileChannel fosChannel = null;
         try {
             // ServerSocketChannel open = ServerSocketChannel.open();
             fis = new FileInputStream("1.jpg");
             fos = new FileOutputStream("2.jpg");
             fisChannel = fis.getChannel();
             fosChannel = fos.getChannel();

             // 分配指定大小的缓冲区
             ByteBuffer buf = ByteBuffer.allocateDirect(1024);
             // 将通道中的数据存取缓冲区
             while (fisChannel.read(buf) != -1) {
                 // 读取信息
                 buf.flip();
                 fosChannel.write(buf);

                 buf.clear();

             }
         } catch (FileNotFoundException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         } finally {
             if (fos != null) {
                 try {
                     fos.close();
                 } catch (IOException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
             }
             if (fis != null) {
                 try {
                     fis.close();
                 } catch (IOException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
             }
             if (fosChannel != null) {
                 try {
                     fosChannel.close();
                 } catch (IOException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
             }
             if (fisChannel != null) {
                 try {
                     fisChannel.close();
                 } catch (IOException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
             }
         }
    }

2、使用直接缓冲区读写文件,速度快,不建议使用,占内存

@Test
    public void test4() throws IOException {

         // 读模式
         FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
         // StandardOpenOption.CREATE没有就创建,有就覆盖,StandardOpenOption.CREATE_NEW有就报错
         FileChannel outChannel = FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.WRITE, StandardOpenOption.READ,
                 StandardOpenOption.CREATE);
         // 内存映射文件和ByteBuffer.allocateDirect(1024);直接获取缓冲区一模一样
         // 缓存区目前在物理内存中,直接缓冲区只有ByteBuffer支持
         MappedByteBuffer map = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
         MappedByteBuffer map2 = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());

         // 直接操作缓冲区
         byte[] bs = new byte[map.limit()];
         map.get(bs);
         map2.put(bs);

    }

3、分散与读取,将通道中的内容分散到缓冲区中

/**
     * 分散与读取,将通道中的内容分散到缓冲区中
     *
     * @throws FileNotFoundException
     */
    @Test
    public void test6() throws Exception {
         // 分散读取
         RandomAccessFile raf = new RandomAccessFile("1.txt", "rw");
         // 获取通道
         FileChannel channel = raf.getChannel();

         // 分配指定大小缓冲区
         ByteBuffer allocate = ByteBuffer.allocate(100);
         ByteBuffer allocate2 = ByteBuffer.allocate(1000);
         // 分散读取
         ByteBuffer[] bio = { allocate, allocate2 };
         channel.read(bio);
         for (ByteBuffer byteBuffer : bio) {
             // 改编读模式
             byteBuffer.flip();
         }
         // 将缓冲区转换为数组,从第0个转换到limit
         System.out.println(new String(bio[0].array(), 0, bio[0].limit()));
        System.out.println("======================");
         System.out.println(new String(bio[0].array(), 0, bio[1].limit()));

         // 聚集写入
         RandomAccessFile rsf = new RandomAccessFile("2.txt", "rw");
         FileChannel channel2 = rsf.getChannel();

         channel2.write(bio);

    }

    /**
     * 通道之间传输数据,直接缓冲区复制文件
     *
     * @throws IOException
     */
    @Test
    public void test5() throws IOException {
         // 读模式
         FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
         // StandardOpenOption.CREATE没有就创建,有就覆盖,StandardOpenOption.CREATE_NEW有就报错
         FileChannel outChannel = FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.WRITE, StandardOpenOption.READ,
                 StandardOpenOption.CREATE);
         // 从哪到哪去
         inChannel.transferTo(0, inChannel.size(), outChannel);
         outChannel.transferFrom(inChannel, 0, inChannel.size());
         inChannel.close();
         outChannel.close();
    }

    /**
     * 直接缓冲区进行文件费复制
     *
     * @throws IOException
     */
    @Test
    public void test4() throws IOException {

         // 读模式
         FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
         // StandardOpenOption.CREATE没有就创建,有就覆盖,StandardOpenOption.CREATE_NEW有就报错
         FileChannel outChannel = FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.WRITE, StandardOpenOption.READ,
                 StandardOpenOption.CREATE);
         // 内存映射文件和ByteBuffer.allocateDirect(1024);直接获取缓冲区一模一样
         // 缓存区目前在物理内存中,直接缓冲区只有ByteBuffer支持
         MappedByteBuffer map = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
         MappedByteBuffer map2 = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());

         // 直接操作缓冲区
         byte[] bs = new byte[map.limit()];
         map.get(bs);
         map2.put(bs);

    }

    /**
     * 非直接缓冲区实现文件复制
     */

    @Test
    public void test3() {

         FileInputStream fis = null;
         FileOutputStream fos = null;
         FileChannel fisChannel = null;
         FileChannel fosChannel = null;
         try {
             // ServerSocketChannel open = ServerSocketChannel.open();
             fis = new FileInputStream("1.jpg");
             fos = new FileOutputStream("2.jpg");
             fisChannel = fis.getChannel();
             fosChannel = fos.getChannel();

             // 分配指定大小的缓冲区
             ByteBuffer buf = ByteBuffer.allocateDirect(1024);
             // 将通道中的数据存取缓冲区
             while (fisChannel.read(buf) != -1) {
                 // 读取信息
                 buf.flip();
                 fosChannel.write(buf);

                 buf.clear();

             }
         } catch (FileNotFoundException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         } finally {
             try {
                 if (fos != null) {
                     fos.close();

                 }
                 if (fis != null) {
                     fis.close();

                 }
                 if (fosChannel != null) {
                     fosChannel.close();
                 }
                 if (fisChannel != null) {
                     fisChannel.close();
                 }
             } catch (IOException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
         }

    }



    @Test
   public void test1() {

         ByteBuffer buf = ByteBuffer.allocate(1024);
         // 可以操作数据的位置
         System.out.println(buf.position());
         // 可以操作数据的大小

         System.out.println(buf.limit());
         // 最大储存容量
         System.out.println(buf.capacity());
         String string = "asd";
         buf.put(string.getBytes());
         // 切换到读取数据模式
         buf.flip();
         // 可重复读数据
         buf.rewind();
         buf.clear();
         // 标记位置
         buf.mark();
         // 回复到标记位置
         buf.reset();
         // 判断缓冲区中是否还有缓冲数据,如果有
         if (buf.hasRemaining()) {
             // 获取缓冲区中可以操作的数量
             System.out.println(buf.remaining());
         }

    }
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会改bug的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值