JAVA NIO
jdk1.4 开始引入了新IO类,NIO包的目的是为了提高IO的效率。
缓冲区Buffer:
缓冲区的优点我就不多介绍了。
拥有3个属性:
(1)容量:一个缓冲区最多容量。
(2)界限:一个缓冲区可读写的范围。
(3)位置:接下来要读写的位置。
界限是用来控制当前读写的范围,如果容量为100,界限为10,则位置只能在0-10之间,即只能读写0-10之间的数据
提供了三个方法改变属性:
(1)clear():把界限移到容量处,把位置设为0.
(2)flip():把界限移到位置处,把位置移到0.
(3)rewind():界限不变,位置设为0.
ByteBuffer:字节缓冲区
创建:ByteBuffer bf = ByteBuffer.allocate(capacity);
MappedByteBuffer:ByteBuffer的子类
能够把文件的部分映射到缓冲区中。
方法:
get();
put();
bb.isRemaining();判断是否还有数据可读
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class TransferDemo{
public static void main(String args[])throws Exception{
FileChannel in = new FileInputStream("test.txt").getChannel();
FileChannel out = new FileOutputStream("out.txt").getChannel();
ByteBuffer bf = ByteBuffer.allocate(1024);
while(in.read(bf)!=-1){
bf.flip();
out.write(bf);
bf.clear();
}
out.close();
in.close();
}
}
疑问:光有Buffer,但是怎么和数据源和数据汇进行连接呢?
Channel通道:把数据源或数据汇和Buffer连接起来。
FileChannel是一个实现好的类,是文件和缓冲区的通道,在FileInputStream、FileOutputStream、RandomAccessFile中的getChannel();获得。
(1)read(ByteBuffer bf); 读取文件数据到ByteBuffer中
(2)write(ByteBuffer bf); 把ByteBuffer写入文件
把String包装到ByteBuffer中:ByteBuffer.wrap (str.getBytes());
利用Charset能够对ByteBuffer进行编码转换。
Charset cs = Charset.forName("UTF-8");
CharBuffer cs.decode(ByteBuffer);把ByteBuffer解码为Unicode编码并返回。
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
public class FileChannelDemo01{
public static void main(String args[])throws Exception{
FileChannel fc = new FileOutputStream("text.txt").getChannel();
fc.write(ByteBuffer.wrap("你好".getBytes()));
fc.close();
fc = new RandomAccessFile("text.txt","rw").getChannel();
fc.position(fc.size());
fc.write(ByteBuffer.wrap("朋友".getBytes()));
fc.close();
fc = new FileInputStream("text.txt").getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024);
fc.read(buf);
buf.flip();
Charset cs = Charset.defaultCharset();
System.out.println(cs.decode(buf));
fc.close();
}
}
Charset类:字符编码转换类
Charset cs = Charset.defaultCharset();
Charset cs = Charset.forName("UTF-8");
获得字符集
UTF-16BE是Unicode码。
ByteBuffer encode(String);把String按照指定的字符集编码,并返回。
CharBuffer decode(ByteBuffer)按照指定的字符集转换成Unicode码。
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class CharsetConvert{
public static void main(String args[])throws Exception{
ByteBuffer bb = ByteBuffer.wrap("你好".getBytes("UTF-8"));
CharBuffer cb = bb.asCharBuffer();
System.out.println(cb);
bb = ByteBuffer.wrap("你好".getBytes("UTF-16BE"));
cb = bb.asCharBuffer();
System.out.println(cb);
}
}
MappedByteBuffer:映射缓冲区
ByteBuffer的子类,用于因为文件太大不能放入内存的文件,能够映射文件的部分区域。
MappedByteBuffer b = channel.map(FileChannel.MapMode.READ_WRITE,pos,capacity); pos表示文件开始映射位置,capacity表示要映射的容量。
import java.nio.*;
import java.io.*;
import java.nio.channels.*;
import java.nio.charset.*;
public class MappedByteBufferDemo01{
public static void main(String args[])throws Exception{
int capacity = 0x8000000;
MappedByteBuffer mb = new RandomAccessFile("test.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE,0,capacity);
mb.put("你好".getBytes("GBK"));
mb.flip();
System.out.println(Charset.forName("GBK").decode(mb));
}
}
缓冲区视图:
ByteBuffer提供了一些方法可以得到其他的视图,比如asCharBuffer()获得CharBuffer。
(1)CharBuffer cb = bb.asCharBuffer();
(2)IntBuffer ib = bb.asIntBuffer();
ByteBuffer提供了
getInt()用于读取整数缓冲区视图put进去的整数。
getChar()用于读取字符缓冲区视图put进去的字符。
import java.nio.*;
public class BufferViewDemo{
public static void main(String args[])throws Exception{
ByteBuffer bb = ByteBuffer.allocate(100);
CharBuffer cb = bb.asCharBuffer();
cb.put("你好");
bb.rewind();
/*while(bb.hasRemaining()){
System.out.println(bb.getChar());
}*/
IntBuffer ib = bb.asIntBuffer();
int[] arr = {1,2,3};
ib.put(arr);
System.out.println(ib.get(2));
ib.flip();
while(ib.hasRemaining()){
int i = ib.get();
System.out.println(i);
}
}
}
文件加锁:
得到锁并加锁:FileLock lock = channel.tryLock();
释放锁:lock.release();
上一篇: JPA(六)多对多
下一篇: NIO 编程示例代码