Java NIO 讀取文件、寫入文件、讀取寫入混合

前言java

Java NIO(new/inputstream outputstream)使用通道、緩衝來操做流,因此要深入理解這些概念,尤爲是,緩衝中的數據結構(當前位置(position)、限制(limit)、容量(capacity)),這些知識點要經過寫程序慢慢體會。數據結構

 

NIO vs  傳統IO異步

NIO是面向緩衝、通道的;傳統IO面向流spa

通道是雙向的既能夠寫、也能夠讀;傳統IO只能是單向的3d

NIO能夠設置爲異步;傳統IO只能是阻塞,同步的code

 

 

緩衝區結構圖blog

NIO是面向緩衝區的,緩衝區能夠理解爲一塊內存,有大小。緩衝區有位置、界限、容量幾個概念。ip

 

capacity:容量,緩衝區的大小內存

limit:限制,表示最大的可讀寫的數量ci

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 }
相關文章
相關標籤/搜索