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 }
相关文章
相关标签/搜索