zoukankan      html  css  js  c++  java
  • Java NIO 读取文件、写入文件、读取写入混合

    前言

    Java NIO(new/inputstream outputstream)使用通道、缓冲来操作流,所以要深刻理解这些概念,尤其是,缓冲中的数据结构(当前位置(position)、限制(limit)、容量(capacity)),这些知识点要通过写程序慢慢体会。

     

    NIO vs  传统IO

    NIO是面向缓冲、通道的;传统IO面向流

    通道是双向的既可以写、也可以读;传统IO只能是单向的

    NIO可以设置为异步;传统IO只能是阻塞,同步的

     

     

    缓冲区结构图

    NIO是面向缓冲区的,缓冲区可以理解为一块内存,有大小。缓冲区有位置、界限、容量几个概念。

     

    capacity:容量,缓冲区的大小

    limit:限制,表示最大的可读写的数量

    position:当前位置,每当读写,当前位置都会加一

     

    flip和clear方法,内部就操作这三个变量。

     

     

    缓冲区常用方法

    clear:将当前位置设置为0,限制设置为容量,目的是尽最大可能让字节,由通道读取到缓冲中

    flip:当前位置置为限制,然后将当前位置置为0,目的是将有数据部分的字节,由缓冲写入到通道中。通常用在读与写之间。

     

    读写文件代码

      1 package com.nio;
      2 
      3 import java.io.*;
      4 import java.nio.ByteBuffer;
      5 import java.nio.channels.FileChannel;
      6 import java.nio.charset.Charset;
      7 
      8 public class TestJavaNio {
      9 
     10     public static String pathname = "d://read.txt";
     11     public static String filename = "d://write.txt";
     12 
     13     @SuppressWarnings("resource")
     14     public static void main(String[] args) {
     15         readNIO();
     16         writeNIO();
     17         //testReadAndWriteNIO();
     18     }
     19 
     20     public static void readNIO() {
     21         FileInputStream fin = null;
     22         try {
     23             fin = new FileInputStream(new File(pathname));
     24             FileChannel channel = fin.getChannel();
     25 
     26             int capacity = 1000;// 字节
     27             ByteBuffer bf = ByteBuffer.allocate(capacity);
     28             System.out.println("限制是:" + bf.limit() + ",容量是:" + bf.capacity() + " ,位置是:" + bf.position());
     29             int length = -1;
     30 
     31             while ((length = channel.read(bf)) != -1) {
     32 
     33                 /*
     34                  * 注意,读取后,将位置置为0,将limit置为容量, 以备下次读入到字节缓冲中,从0开始存储
     35                  */
     36                 bf.clear();
     37                 byte[] bytes = bf.array();
     38                 System.out.println("start..............");
     39 
     40                 String str = new String(bytes, 0, length);
     41                 System.out.println(str);
     42                 //System.out.write(bytes, 0, length);
     43 
     44                 System.out.println("end................");
     45 
     46                 System.out.println("限制是:" + bf.limit() + "容量是:" + bf.capacity() + "位置是:" + bf.position());
     47 
     48             }
     49 
     50             channel.close();
     51 
     52         } catch (FileNotFoundException e) {
     53             e.printStackTrace();
     54         } catch (IOException e) {
     55             e.printStackTrace();
     56         } finally {
     57             if (fin != null) {
     58                 try {
     59                     fin.close();
     60                 } catch (IOException e) {
     61                     e.printStackTrace();
     62                 }
     63             }
     64         }
     65     }
     66 
     67     public static void writeNIO() {
     68         FileOutputStream fos = null;
     69         try {
     70 
     71             fos = new FileOutputStream(new File(filename));
     72             FileChannel channel = fos.getChannel();
     73             ByteBuffer src = Charset.forName("utf8").encode("你好你好你好你好你好");
     74             // 字节缓冲的容量和limit会随着数据长度变化,不是固定不变的
     75             System.out.println("初始化容量和limit:" + src.capacity() + ","
     76                     + src.limit());
     77             int length = 0;
     78 
     79             while ((length = channel.write(src)) != 0) {
     80                 /*
     81                  * 注意,这里不需要clear,将缓冲中的数据写入到通道中后 第二次接着上一次的顺序往下读
     82                  */
     83                 System.out.println("写入长度:" + length);
     84             }
     85 
     86         } catch (FileNotFoundException e) {
     87             e.printStackTrace();
     88         } catch (IOException e) {
     89             e.printStackTrace();
     90         } finally {
     91             if (fos != null) {
     92                 try {
     93                     fos.close();
     94                 } catch (IOException e) {
     95                     e.printStackTrace();
     96                 }
     97             }
     98         }
     99     }
    100 
    101     public static void testReadAndWriteNIO() {
    102         FileInputStream fin = null;
    103         FileOutputStream fos = null;
    104         try {
    105             fin = new FileInputStream(new File(pathname));
    106             FileChannel channel = fin.getChannel();
    107 
    108             int capacity = 100;// 字节
    109             ByteBuffer bf = ByteBuffer.allocate(capacity);
    110             System.out.println("限制是:" + bf.limit() + "容量是:" + bf.capacity() + "位置是:" + bf.position());
    111             int length = -1;
    112 
    113             fos = new FileOutputStream(new File(filename));
    114             FileChannel outchannel = fos.getChannel();
    115 
    116 
    117             while ((length = channel.read(bf)) != -1) {
    118 
    119                 //将当前位置置为limit,然后设置当前位置为0,也就是从0到limit这块,都写入到同道中
    120                 bf.flip();
    121 
    122                 int outlength = 0;
    123                 while ((outlength = outchannel.write(bf)) != 0) {
    124                     System.out.println("读," + length + "写," + outlength);
    125                 }
    126 
    127                 //将当前位置置为0,然后设置limit为容量,也就是从0到limit(容量)这块,
    128                 //都可以利用,通道读取的数据存储到
    129                 //0到limit这块
    130                 bf.clear();
    131 
    132             }
    133         } catch (FileNotFoundException e) {
    134             e.printStackTrace();
    135         } catch (IOException e) {
    136             e.printStackTrace();
    137         } finally {
    138             if (fin != null) {
    139                 try {
    140                     fin.close();
    141                 } catch (IOException e) {
    142                     e.printStackTrace();
    143                 }
    144             }
    145             if (fos != null) {
    146                 try {
    147                     fos.close();
    148                 } catch (IOException e) {
    149                     e.printStackTrace();
    150                 }
    151             }
    152         }
    153     }
    154 
    155 }
  • 相关阅读:
    select下拉框运用
    oracleINS-13001 环境不满足最低要求
    组成原理-存储器
    操作系统-- 存储器
    组成原理-CPU
    计算机网络-tcp-ip
    操作系统-处理机
    数据链路层~计算机网络
    物理层--计算机网络
    JavaScript-轮播2
  • 原文地址:https://www.cnblogs.com/cxxjohnson/p/9082567.html
Copyright © 2011-2022 走看看