package com.part01; import java.nio.Buffer;//是内存区域,类似于数组 import java.nio.ByteBuffer; import org.junit.Test; public class Demo01 { @Test//在方法上加@意味着可以被测试 JUnit(导jar包) public void testFlip() { ByteBuffer buffer = ByteBuffer.allocate(10); info(buffer); buffer.put((byte) 23); buffer.put((byte) 24); info(buffer); buffer.flip();// 将 position放到0 limit放到原position 的位置, p--l之间是有效数据 info(buffer); } @Test public void testClean() { ByteBuffer buffer=ByteBuffer.allocate(10); info(buffer); buffer.put((byte) 23); buffer.put((byte) 24); info(buffer); buffer.flip(); info(buffer); //将p放到0 l和c放到最末尾,等待下一次读 buffer.clear(); info(buffer); } @Test public void testremain() { ByteBuffer buffer=ByteBuffer.allocate(10); info(buffer); buffer.put((byte) 23); buffer.put((byte) 24); info(buffer); buffer.flip(); info(buffer); //在p ---l这间有没有东西 if(buffer.hasRemaining()) { //p--l之间的东西个数 System.out.println(buffer.remaining()); } } @Test public void testwind() { ByteBuffer buffer=ByteBuffer.allocate(10); info(buffer); buffer.put((byte) 23); buffer.put((byte) 24); info(buffer); //将p设为0,值没有没变 buffer.rewind(); info(buffer); System.out.println(buffer.get()); System.out.println(buffer.get()); } public static void info(Buffer buf) { System.out.println("position:"+buf.position()+"----limit:"+buf.limit()+"----->capacity"+buf.capacity()); } }
依次测试testFlip,testClean,testremain,testwind结果如下:
position:0----limit:10----->capacity10 position:2----limit:10----->capacity10 position:0----limit:2----->capacity10 position:0----limit:10----->capacity10 position:2----limit:10----->capacity10 position:0----limit:2----->capacity10 position:0----limit:10----->capacity10 position:0----limit:10----->capacity10 position:2----limit:10----->capacity10 position:0----limit:2----->capacity10 2 position:0----limit:10----->capacity10 position:2----limit:10----->capacity10 position:0----limit:10----->capacity10 23 24
Bytebuffer与字符串之间的互转
package com.part01;
//java.nio.charset.Charset类
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import org.junit.Test;
/*CharBuffer decode(ByteBuffer bb) 将此 charset 中的字节解码成 Unicode 字符的便捷方法。
ByteBuffer encode(String str) 将此 charset中的字符串编码成字节的便捷方法。
static Charset forName(String charsetName) 返回指定 charset的charset 对象。
defaultCharset() 返回此 Java虚拟机的默认 charset。 */
public class Demo02
{
@Test
public void bytebuffer2string()//ByteBuffer转字符串
{
ByteBuffer buf=ByteBuffer.allocate(10);
buf.put((byte)97);
buf.put((byte)98);
buf.put((byte)99);
buf.flip();
CharBuffer charbuffer=Charset.defaultCharset().decode(buf);
System.out.println(charbuffer);
}
@Test
public void String2ByteBuffer()//字符串转ByteBuffer
{
String str="abc";
Charset charset=Charset.forName("utf-8");
ByteBuffer buf=charset.encode(str);
System.out.println("position:"+buf.position()+"----limit:"+buf.limit()+"----->capacity"+buf.capacity());
}
}
nio的思想和实现
写东西
package com.part01;
import java.io.FileNotFoundException;
public class Demo03 {
public static void main(String[] args) throws IOException
{
FileOutputStream fo=new FileOutputStream("d:\\iodemo.txt");
//输出流得到的FileChannel只能输出
FileChannel fc=fo.getChannel();
String str="张三回来了吗";
ByteBuffer buf=Charset.defaultCharset().encode(str);
fc.write(buf);
fc.close();
fo.close();
System.out.println("OK");
}
}
等同于
package com.part01;
import java.io.FileOutputStream;
public class Demo04 {
public static void main(String[] args) throws IOException
{
FileOutputStream fo=new FileOutputStream("d:\\iodemo.txt");
//输出流得到的FileChannel只能输出
FileChannel fc=fo.getChannel();
String str="张三回来了吗";
byte[] data=str.getBytes();
ByteBuffer buf=ByteBuffer.allocate(50);
buf.put(data);
buf.flip();//p--l之间的有效数
fc.write(buf);//channel可以读写buffer
fo.close();
fc.close();
System.out.println("OK");
}
}
读东西
package com.part01;
import java.io.FileInputStream;
public class Demo05 {
public static void main(String[] args) throws Exception{
// Charset set=Charset.defaultCharset();
//输入流得到的FileChannel只能写
FileInputStream fi=new FileInputStream("d:\\iodemo.txt");
FileChannel fc=fi.getChannel();
ByteBuffer buf=ByteBuffer.allocate(4096);
info(buf);
int len=-1;
while((len=fc.read(buf))>0)
{
info(buf);
buf.flip();
String str=Charset.defaultCharset().decode(buf).toString();
System.out.println(str);
buf.clear();//在下一次读之前
}
fc.close();
fi.close();
}
public static void info(Buffer buf)
{
System.out.println("position:"+buf.position()+"----limit:"+buf.limit()+"----->capacity"+buf.capacity());
}
}
//在ByteBuffer里面拿数据的时候,一定要先flip
//从流中往ByteBuffer中读数据一定要clear
用java.nio来复制文件(虚拟内存映射模式)
package com.part10;
import java.io.FileInputStream;
//用java.nio来复制文件(虚拟内存映射模式)
public class Demo06 {
public static void main(String[] args) throws IOException
{
FileInputStream fi=new FileInputStream("D:\\tools\\eclipse-jee-oxygen-3-win32-x86_64.zip");
FileOutputStream fo=new FileOutputStream("c:\\eclipse.zip");
FileChannel fic=fi.getChannel();
FileChannel foc=fo.getChannel();
ByteBuffer buffer=ByteBuffer.allocate(4096);
long start= System.currentTimeMillis();
int len=-1;
while((len=fic.read(buffer))>0)//读到数据,要把数据写到输出流
{
buffer.flip();
foc.write(buffer);
buffer.clear();//在下一次读之前
}
fic.close();
foc.close();
long end= System.currentTimeMillis();
System.out.println((end-start)/1000.0);
}
}