java亟需关注的知识点-I0之新IO(NI0)
java需要关注的知识点---I0之新IO(NI0)
缓冲器操纵数据:
ByteBuffer是数据移进移出通道的唯一方式,使用ByteBuffer.wrap把子节数组包装起来然后用getChannel()方法在FileInputStream上打开一个通道,接着将来自于ByteBuffer的数据写入到FileChannel中。
ByteBuffer的方法详细:
capacity()--->返回缓冲区容量
clear() --->清空缓冲区,将position设置为0,limit设置为容量。调用此方法可以覆写缓冲区。
flip() ---> 将limit设置为position,position设置为0,此方法用于准备从缓冲区读取已经写入的数据。
limit() --->返回limit的值。
limit(int limit)---> 设置limit的值
mark() ---> 将mark设置为position.
position() ---> 返回position的值。
position(int pos) --->设置position的值。
remaining() ---> 返回(limit - position)
hasRemainging() --> 若有介于position和limit之间的元素,返回true.
mark---->标记 position ----->位置 limit----> 界限 capacity-->容量
FileInputStream,FileOutputStream 和 RandomAccessFile 和FileChannel的转换
使用allocateDirect()提高速度。
使用transferTo/treansferFrom将一个管道和另外一个管道相通,达到上面copy的效果。
使用CharBuffer的asCharBuffer()方法读数据:
转换数据(详解Charset):
get date from bytebuffer:
使用IntBuffer存储int:
byteBuffer转换其他类型buffer:
ByteBuffer默认是以高位优先的形式存储数据的,可以使用ByteOrder.BIG_ENDIAN 或者ByteOrder.LITLE_ENDIAN改变ByteBuffer的字节排序方式,数据在网上传递时,也常常是以高位优先的形式。通过以下程序来改变字节顺序。
输出结果:
[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102]
ByteOrder.BIG_ENDIAN:[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102]
ByteOrder.LITTLE_ENDIAN:[97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0]
缓冲器操纵数据:
ByteBuffer是数据移进移出通道的唯一方式,使用ByteBuffer.wrap把子节数组包装起来然后用getChannel()方法在FileInputStream上打开一个通道,接着将来自于ByteBuffer的数据写入到FileChannel中。
ByteBuffer的方法详细:
capacity()--->返回缓冲区容量
clear() --->清空缓冲区,将position设置为0,limit设置为容量。调用此方法可以覆写缓冲区。
flip() ---> 将limit设置为position,position设置为0,此方法用于准备从缓冲区读取已经写入的数据。
limit() --->返回limit的值。
limit(int limit)---> 设置limit的值
mark() ---> 将mark设置为position.
position() ---> 返回position的值。
position(int pos) --->设置position的值。
remaining() ---> 返回(limit - position)
hasRemainging() --> 若有介于position和limit之间的元素,返回true.
mark---->标记 position ----->位置 limit----> 界限 capacity-->容量
FileInputStream,FileOutputStream 和 RandomAccessFile 和FileChannel的转换
public class GetChannel { private static final int BSIZE = 1024; public static void main(String[] args) throws IOException { FileChannel fc = new FileOutputStream("data.txt").getChannel(); fc.write(ByteBuffer.wrap("Some text".getBytes())); fc.close(); fc = new RandomAccessFile("data.txt","rw").getChannel(); fc.position(fc.size());//move to the end fc.write(ByteBuffer.wrap("Some more".getBytes())); fc.close(); fc = new FileInputStream("data.txt").getChannel(); ByteBuffer buff = ByteBuffer.allocate(BSIZE); fc.read(buff); buff.flip(); while(buff.hasRemaining()) System.out.print((char)buff.get()); } }
使用allocateDirect()提高速度。
public class ChannelCopy { private static final int BSIZE = 1024; /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { System.out.println(args.length); if (args.length != 2) { System.out.println("arguments: sourcefile destfile"); System.exit(1); } System.out.println(args[0]); FileChannel in = new FileInputStream(args[0]).getChannel(); System.out.println(args[1]); FileChannel out = new FileOutputStream(args[1]).getChannel(); ByteBuffer buff = ByteBuffer.allocateDirect(BSIZE); while ((in.read(buff)) != -1) { buff.flip(); out.write(buff); buff.clear(); } } }
使用transferTo/treansferFrom将一个管道和另外一个管道相通,达到上面copy的效果。
public class TransferTo { private static final int BSIZE = 1024; /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { if (args.length != 2) { System.out.println("arguments: sourcefile destfile"); System.exit(1); } System.out.println(args[0]); FileChannel in = new FileInputStream(args[0]).getChannel(); System.out.println(args[1]); FileChannel out = new FileOutputStream(args[1]).getChannel(); ByteBuffer buff = ByteBuffer.allocateDirect(BSIZE); in.transferTo(0, in.size(), out); // or: out.treansferFrom(in,0,in.size()); } }
使用CharBuffer的asCharBuffer()方法读数据:
public class BufferToText { private static final int BSIZE = 1024; /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { FileChannel fc = new FileOutputStream("data2.txt").getChannel(); fc.write(ByteBuffer.wrap("Some Text".getBytes())); fc.close(); fc = new FileInputStream("data2.txt").getChannel(); ByteBuffer buff = ByteBuffer.allocate(BSIZE); fc.read(buff); buff.flip(); System.out.println(buff.asCharBuffer()); System.out.println("-----example 1 end-----"); buff.rewind(); String encoding = System.getProperty("file.encoding"); System.out.println("Decoded using " + encoding + ":" + Charset.forName(encoding).decode(buff)); fc = new FileOutputStream("data2.txt").getChannel(); fc.write(ByteBuffer.wrap("some text".getBytes("UTF-16BE"))); fc.close(); fc = new FileInputStream("data2.txt").getChannel(); buff.clear(); fc.read(buff); buff.flip(); System.out.println(buff.asCharBuffer()); System.out.println("-----example 2 end-----"); fc = new FileOutputStream("data2.txt").getChannel(); buff = ByteBuffer.allocate(18); buff.asCharBuffer().put("Some text"); fc.write(buff); fc.close(); fc = new FileInputStream("data2.txt").getChannel(); buff.clear(); fc.read(buff); buff.flip(); fc.close(); System.out.println(buff.asCharBuffer()); System.out.println("-----example 3 end-----"); } }
转换数据(详解Charset):
public class AvailableCharSets { /** * @param args */ public static void main(String[] args) { SortedMap<String,Charset> charset = Charset.availableCharsets(); Iterator<String> it = charset.keySet().iterator(); while(it.hasNext()) { String csName = it.next(); System.out.print("name:" + csName); Iterator aliase = charset.get(csName).aliases().iterator(); if(aliase.hasNext()) System.out.print(":" + aliase.next()); while(aliase.hasNext()) { System.out.print(":"+aliase.next()); if(aliase.hasNext()) System.out.print(","); } System.out.println(); } } }
get date from bytebuffer:
public class GetData { private static final int BSIZE = 1024; public static void main(String[] args) { ByteBuffer bb = ByteBuffer.allocate(BSIZE); int i = 0; while(i ++<bb.limit()) System.out.print("nonzero"); System.out.println("i = " + i); bb.rewind(); bb.asCharBuffer().put("HowDay"); char c; while((c = bb.getChar()) != 0) { System.out.print(c + " "); } System.out.println(); bb.rewind(); bb.asShortBuffer().put((short)471142); System.out.println(bb.getShort()); bb.rewind(); bb.asIntBuffer().put(99471142); System.out.println(bb.getInt()); bb.rewind(); bb.asLongBuffer().put(99471142); System.out.println(bb.getLong()); bb.rewind(); bb.asFloatBuffer().put(99471142); System.out.println(bb.getFloat()); bb.rewind(); bb.asDoubleBuffer().put(99411147.32); System.out.println(bb.getDouble()); bb.rewind(); } }
使用IntBuffer存储int:
public class InBufferDemo { private static final int BSIZE = 1024; public static void main(String args[]) { ByteBuffer bb = ByteBuffer.allocate(BSIZE); IntBuffer ib = bb.asIntBuffer(); ib.put(new int[]{11,42,47,99,143,811,1016}); System.out.println(ib.get(3)); ib.put(3,1181); System.out.println(ib.get(3)+":"); //set a new limit before rewinding the buffer. ib.flip(); while(ib.hasRemaining()) { int i = ib.get(); System.out.println(i); } } }
byteBuffer转换其他类型buffer:
public class ViewBuffers { private static final int BSIZE = 1024; public static void main(String[] args) { ByteBuffer bb = ByteBuffer.wrap(new byte[]{0,0,0,0,0,0,0,'a'}); bb.rewind(); System.out.println("ByteBuffer"); while(bb.hasRemaining()) { System.out.print(bb.position() + "-->" + bb.get()+ ","); } System.out.println("byte end!"); CharBuffer cb = ((ByteBuffer)bb.rewind()).asCharBuffer(); while(cb.hasRemaining()) { System.out.print(cb.position() + "-->" + cb.get() + ","); } System.out.println("char end!"); FloatBuffer fb = ((ByteBuffer)bb.rewind()).asFloatBuffer(); while(fb.hasRemaining()) { System.out.print(fb.position() + "-->" + fb.get() + ","); } System.out.println("float end!"); IntBuffer ib = ((ByteBuffer)bb.rewind()).asIntBuffer(); while(ib.hasRemaining()) { System.out.print(ib.position() + "-->" + ib.get() + ","); } System.out.println("int end!"); LongBuffer lb = ((ByteBuffer)bb.rewind()).asLongBuffer(); while(lb.hasRemaining()) { System.out.print(lb.position() + "-->" + lb.get() + ","); } System.out.println("Long end!"); ShortBuffer sb = ((ByteBuffer)bb.rewind()).asShortBuffer(); while(sb.hasRemaining()) { System.out.print(sb.position() + "-->" + sb.get() + ","); } System.out.println("Short end!"); DoubleBuffer db = ((ByteBuffer)bb.rewind()).asDoubleBuffer(); while(db.hasRemaining()) { System.out.print(db.position() + "-->" + db.get() + ","); } System.out.println("Double end!"); } }
ByteBuffer默认是以高位优先的形式存储数据的,可以使用ByteOrder.BIG_ENDIAN 或者ByteOrder.LITLE_ENDIAN改变ByteBuffer的字节排序方式,数据在网上传递时,也常常是以高位优先的形式。通过以下程序来改变字节顺序。
public class Endians { public static void main(String[] args) { ByteBuffer bb = ByteBuffer.wrap(new byte[12]); bb.asCharBuffer().put("abcdef"); System.out.println(Arrays.toString(bb.array())); bb.rewind(); bb.order(ByteOrder.BIG_ENDIAN); bb.asCharBuffer().put("abcdef"); System.out.println("ByteOrder.BIG_ENDIAN:" + Arrays.toString(bb.array())); bb.rewind(); bb.order(ByteOrder.LITTLE_ENDIAN); bb.asCharBuffer().put("abcdef"); System.out.println("ByteOrder.LITTLE_ENDIAN:" + Arrays.toString(bb.array())); } }
输出结果:
[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102]
ByteOrder.BIG_ENDIAN:[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102]
ByteOrder.LITTLE_ENDIAN:[97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0]