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的转换
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 endfc.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]