`

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 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]
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics