第18章 java I/O系统(3)
18.10 新I/O
新I/O速度的提高来自于所使用的结构更接近于操作系统执行I/O的方式:通道和缓冲器。我们并没有字节和通道交互;我们只是和缓冲器交互。并把缓冲器派送到通道。通道要么从缓冲器获得数据,要么向缓冲器发送数据。
唯一直接与通道交互的缓冲器是ByteBuffer。
1 package com.thinkinjava.chapter18.part10; 2 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.RandomAccessFile; 6 import java.nio.ByteBuffer; 7 import java.nio.channels.FileChannel; 8 9 public class GetChannel { 10 private static final int BSIZE = 1024; 11 12 @SuppressWarnings("resource") 13 public static void main(String[] args) throws Exception { 14 15 //写一个文件 16 FileChannel fc = new FileOutputStream("src/com/thinkinjava/chapter18/part10/data.txt").getChannel(); 17 fc.write(ByteBuffer.wrap("Some text ".getBytes())); 18 fc.close(); 19 20 //在文件的末尾追加字符 21 fc = new RandomAccessFile("src/com/thinkinjava/chapter18/part10/data.txt", "rw").getChannel(); 22 fc.position(fc.size()); 23 fc.write(ByteBuffer.wrap("Some more".getBytes())); 24 fc.close(); 25 26 //读文件 27 fc = new FileInputStream("src/com/thinkinjava/chapter18/part10/data.txt").getChannel(); 28 //对于只读访问,我们必须显示地使用静态的allocate()方法类分配ByteBuffer。 29 ByteBuffer buff = ByteBuffer.allocate(BSIZE); 30 fc.read(buff); 31 //一旦调用read()来告知FileChannel向ByteBuffer存储字节,就必须调用缓冲器上的额flip() 32 buff.flip(); 33 34 while(buff.hasRemaining()) 35 System.out.print((char)buff.get()); 36 37 38 } 39 40 }
1 package com.thinkinjava.chapter18.part10; 2 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.nio.ByteBuffer; 7 import java.nio.channels.FileChannel; 8 9 public class ChannelCopy { 10 11 private static final int BSIZE = 1024; 12 13 14 @SuppressWarnings("resource") 15 public static void main(String[] args) throws IOException { 16 17 args = new String[]{"src/com/thinkinjava/chapter18/part10/data.txt","src/com/thinkinjava/chapter18/part10/data1.txt"}; 18 19 if(args.length != 2){ 20 System.out.println("arguments: sourcefile destfile"); 21 System.exit(1); 22 } 23 24 FileChannel in = new FileInputStream(args[0]).getChannel(), 25 out = new FileOutputStream(args[1]).getChannel(); 26 27 ByteBuffer buffer = ByteBuffer.allocate(BSIZE); 28 29 while(in.read(buffer) != -1){ 30 buffer.flip();//准备写操作 31 out.write(buffer); 32 buffer.clear();//准备读操作 33 } 34 35 36 37 38 39 } 40 41 42 }
1 package com.thinkinjava.chapter18.part10; 2 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.nio.channels.FileChannel; 7 8 public class TransferTo { 9 10 @SuppressWarnings("resource") 11 public static void main(String[] args) throws IOException { 12 13 args = new String[] { "src/com/thinkinjava/chapter18/part10/data.txt", 14 "src/com/thinkinjava/chapter18/part10/data2.txt" }; 15 16 if (args.length != 2) { 17 System.out.println("arguments: sourcefile destfile"); 18 System.exit(1); 19 } 20 21 FileChannel in = new FileInputStream(args[0]).getChannel(), out = new FileOutputStream( 22 args[1]).getChannel(); 23 24 //transferTo()和transferFrom()则允许将一个通道和另一个通道直接相连 25 in.transferTo(0, in.size(), out); 26 // out.transferFrom(in, 0, in.size()); 27 28 } 29 30 }
18.10.1 转换数据
1 package com.thinkinjava.chapter18.part10; 2 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.nio.ByteBuffer; 6 import java.nio.channels.FileChannel; 7 import java.nio.charset.Charset; 8 9 public class BufferToText { 10 11 private static final int BISZE = 1024; 12 13 //缓冲容器容纳的是普通的字节,为了把他们转换成字符,我们要在输入它们的时候对其进行编码, 14 //要么在将其从缓冲器输出时对他们呢进行解码 15 @SuppressWarnings("resource") 16 public static void main(String[] args) throws Exception { 17 18 FileChannel fc = new FileOutputStream("src/com/thinkinjava/chapter18/part10/data2.txt").getChannel(); 19 20 fc.write(ByteBuffer.wrap("Some text".getBytes())); 21 fc.close(); 22 23 fc = new FileInputStream("src/com/thinkinjava/chapter18/part10/data2.txt").getChannel(); 24 ByteBuffer buffer = ByteBuffer.allocate(BISZE); 25 fc.read(buffer); 26 buffer.flip(); 27 28 //没有效果 29 System.out.println(buffer.asCharBuffer()); 30 //用系统自带的字符集解码 31 buffer.rewind(); 32 String encoding = System.getProperty("file.encoding"); 33 34 System.out.println("Decoded using "+encoding+":"+Charset.forName(encoding).decode(buffer)); 35 36 fc = new FileOutputStream("src/com/thinkinjava/chapter18/part10/data2.txt").getChannel(); 37 38 fc.write(ByteBuffer.wrap("Some text".getBytes("UTF-16BE"))); 39 fc.close(); 40 41 //不再重新读入 42 fc = new FileInputStream("src/com/thinkinjava/chapter18/part10/data2.txt").getChannel(); 43 buffer.clear(); 44 fc.read(buffer); 45 buffer.flip(); 46 System.out.println(buffer.asCharBuffer()); 47 48 // 49 fc = new FileOutputStream("src/com/thinkinjava/chapter18/part10/data2.txt").getChannel(); 50 buffer = ByteBuffer.allocate(24); 51 buffer.asCharBuffer().put("Some text"); 52 fc.write(buffer); 53 fc.close(); 54 55 //读取和显示 56 fc = new FileInputStream("src/com/thinkinjava/chapter18/part10/data2.txt").getChannel(); 57 buffer.clear(); 58 fc.read(buffer); 59 buffer.flip(); 60 System.out.println(buffer.asCharBuffer()); 61 62 63 } 64 65 }
获得系统字符集
1 package com.thinkinjava.chapter18.part10; 2 3 import java.nio.charset.Charset; 4 import java.util.Iterator; 5 import java.util.SortedMap; 6 7 public class AvaiableCharSets { 8 public static void main(String[] args) { 9 10 SortedMap<String, Charset> charSets = Charset.availableCharsets(); 11 12 Iterator<String> it = charSets.keySet().iterator(); 13 14 while(it.hasNext()){ 15 16 String csName = it.next(); 17 System.out.print(csName); 18 19 Iterator<String> aliases = charSets.get(csName).aliases().iterator(); 20 21 if(aliases.hasNext()) 22 System.out.print(":"); 23 while(aliases.hasNext()){ 24 System.out.print(aliases.next()); 25 if(aliases.hasNext()) 26 System.out.print(";"); 27 } 28 System.out.println(""); 29 } 30 31 } 32 }
18.10.2 获取基本类型
1 package com.thinkinjava.chapter18.part10; 2 3 import java.nio.ByteBuffer; 4 5 public class GetData { 6 7 private static final int BSIZE = 1024; 8 9 public static void main(String[] args) { 10 11 12 ByteBuffer bb = ByteBuffer.allocate(BSIZE);//分配容量 13 14 int i = 0; 15 while(i++<bb.limit()) 16 if(bb.get() != 0) 17 print("nonzero"); 18 print("i = "+i); 19 print(); 20 bb.rewind(); 21 22 23 //存储和读取char array 24 bb.asCharBuffer().put("Howdy!"); 25 char c; 26 while((c = bb.getChar()) != 0) 27 printnb(c+" "); 28 print(); 29 bb.rewind(); 30 31 //存储和读取short型 32 bb.asShortBuffer().put((short)471142); 33 print(bb.getInt()); 34 bb.rewind(); 35 36 //存储和读取int 37 bb.asIntBuffer().put(99471142); 38 print(bb.getInt()); 39 bb.rewind(); 40 41 //存储和读取long 42 bb.asLongBuffer().put(99471142); 43 print(bb.getLong()); 44 bb.rewind(); 45 46 47 //存储和读取float 48 bb.asFloatBuffer().put(99471142); 49 print(bb.getFloat()); 50 bb.rewind(); 51 52 //存储和读取double 53 bb.asDoubleBuffer().put(99471142); 54 print(bb.getDouble()); 55 bb.rewind(); 56 57 58 59 60 61 62 63 64 65 66 67 68 } 69 70 private static void printnb(Object obj) { 71 System.out.print(String.valueOf(obj)); 72 } 73 74 private static void print(Object obj) { 75 System.out.print(String.valueOf(obj)); 76 System.out.println(); 77 } 78 private static void print() { 79 System.out.println(); 80 } 81 82 83 84 85 }
18.10.3 视图缓冲器
1 package com.thinkinjava.chapter18.part10; 2 3 import java.nio.ByteBuffer; 4 import java.nio.IntBuffer; 5 6 public class IntBufferDemo { 7 8 private static final int BSIZE = 1024; 9 10 public static void main(String[] args) { 11 12 ByteBuffer bb = ByteBuffer.allocate(BSIZE); 13 IntBuffer ib = bb.asIntBuffer(); 14 15 ib.put(new int[]{11,42,47,99,143,811,1016}); 16 17 System.out.println(ib.get(3)); 18 19 ib.put(3,1811); 20 21 ib.flip(); 22 while(ib.hasRemaining()){ 23 int i = ib.get(); 24 System.out.println(i); 25 } 26 27 28 29 30 31 32 } 33 34 }
1 package com.thinkinjava.chapter18.part10; 2 3 import java.nio.ByteBuffer; 4 import java.nio.CharBuffer; 5 import java.nio.DoubleBuffer; 6 import java.nio.FloatBuffer; 7 import java.nio.IntBuffer; 8 import java.nio.LongBuffer; 9 import java.nio.ShortBuffer; 10 11 public class ViewBuffers { 12 13 public static void main(String[] args) { 14 15 ByteBuffer bb = ByteBuffer.wrap(new byte[]{0,0,0,0,0,0,0,'a'}); 16 bb.rewind(); 17 18 //byte 19 System.out.print("Byte Buffer "); 20 while(bb.hasRemaining()) 21 System.out.print(bb.position()+"->"+bb.get()+",");//Byte Buffer 0->0,1->0,2->0,3->0,4->0,5->0,6->0,7->97, 22 System.out.println(); 23 24 //Char 25 CharBuffer cb = ((ByteBuffer)bb.rewind()).asCharBuffer(); 26 System.out.print("Char Buffer "); 27 while(cb.hasRemaining()) 28 System.out.print(cb.position()+"->"+cb.get()+",");//Char Buffer 0-> ,1-> ,2-> ,3->a 29 System.out.println(); 30 31 //float 32 FloatBuffer fb = ((ByteBuffer)bb.rewind()).asFloatBuffer(); 33 System.out.print("Float Buffer "); 34 while(fb.hasRemaining()) 35 System.out.print(fb.position()+"->"+fb.get()+",");//Float Buffer 0->0.0,1->1.36E-43, 36 System.out.println(); 37 38 //int 39 IntBuffer ib = ((ByteBuffer)bb.rewind()).asIntBuffer(); 40 System.out.print("Int Buffer "); 41 while(ib.hasRemaining()) 42 System.out.print(ib.position()+"->"+ib.get()+",");//Int Buffer 0->0,1->97, 43 System.out.println(); 44 45 46 //long 47 LongBuffer lb = ((ByteBuffer)bb.rewind()).asLongBuffer(); 48 System.out.print("Long Buffer "); 49 while(lb.hasRemaining()) 50 System.out.print(lb.position()+"->"+lb.get()+",");//Long Buffer 0->97, 51 System.out.println(); 52 53 //short 54 ShortBuffer sb = ((ByteBuffer)bb.rewind()).asShortBuffer(); 55 System.out.print("Short Buffer "); 56 while(sb.hasRemaining()) 57 System.out.print(sb.position()+"->"+sb.get()+",");//Short Buffer 0->0,1->0,2->0,3->97, 58 System.out.println(); 59 60 //double 61 DoubleBuffer db = ((ByteBuffer)bb.rewind()).asDoubleBuffer(); 62 System.out.print("Double Buffer "); 63 while(db.hasRemaining()) 64 System.out.print(db.position()+"->"+db.get()+",");//Double Buffer 0->4.8E-322, 65 System.out.println(); 66 67 } 68 69 }
1 package com.thinkinjava.chapter18.part10; 2 3 import java.nio.ByteBuffer; 4 import java.nio.ByteOrder; 5 import java.util.Arrays; 6 7 public class Endians { 8 9 public static void main(String[] args) { 10 11 ByteBuffer bb = ByteBuffer.wrap(new byte[12]); 12 bb.asCharBuffer().put("abcdef"); 13 14 System.out.println(Arrays.toString(bb.array())); 15 bb.rewind(); 16 17 bb.order(ByteOrder.BIG_ENDIAN); 18 bb.asCharBuffer().put("abcdef"); 19 System.out.println(Arrays.toString(bb.array())); 20 bb.rewind(); 21 22 bb.order(ByteOrder.LITTLE_ENDIAN); 23 bb.asCharBuffer().put("abcdef"); 24 System.out.println(Arrays.toString(bb.array())); 25 26 27 } 28 29 }
感觉只是介绍api用法,不写了。。。。