狂java_《疯狂Java讲义》(三十三)---- NIO

Buffer

Buffer没有构造函数,只能通过static XxxBuffer allocate(int capacity) 来创建一个容量为capacity的XxxBuffer.

packagecom.ivy.nio;importjava.nio.CharBuffer;public classBufferDemo {public static voidmain(String[] args) {//TODO Auto-generated method stub

CharBuffer buffer= CharBuffer.allocate(8);

System.out.println("capacity:" +buffer.capacity());

System.out.println("limit:" +buffer.limit());

System.out.println("position:" +buffer.position());

buffer.put("a");

buffer.put("b");

buffer.put("c");

System.out.println("after adding three elements -------");

System.out.println("position:" +buffer.position());

buffer.flip();

System.out.println("after flip -------");

System.out.println("position:" +buffer.position());

System.out.println("position(0):" +buffer.get());

System.out.println("position:" +buffer.position());

buffer.clear();

System.out.println("after clear -------");

System.out.println("limit:" +buffer.limit());

System.out.println("position:" +buffer.position());

System.out.println("position(2):" + buffer.get(2));

System.out.println("position:" +buffer.position());

}

}

三个重要概念,容量,界限,位置:

容量(capacity):缓冲区的容量,最多可以存多少数据。

界限(limit):第一个不应该被读出或写入的缓冲区位置索引,也就是说,位于limit后的数据既不可读,也不可写。

位置(position):用于指明下一个可以被读出的或写入到缓冲区位置索引,当读数据时,positon的值恰好等于已经读了多少数据。

当Buffer装入数据解暑后,调用Buffer的flip方法,该方法将limit设置为position所在的位置,将position设为0,这样buffer就为输出数据做好了准备;当Buffer输出数据结束后,Buffer调用clear方法,它并不是清空数据,仅仅将position位置置为0,将limit置为capacity,这样为再次向Buffer中装入数据做好准备。

使用Channel

Channel类似于传统的流对象,但与传统的流对象有两个主要区别:

Channel可以直接将制定文件的部分或全部直接映射成Buffer。

程序不能直接访问Channel的数据,包括读取,写入都不行,Channel只能与Buffer进行交互。

所有的Channel都不应该通过构造器来直接创建,而是通过传统的节点InputStream,OutputStream的getChannel方法来返回对应的Channel,不同的节点流获得的Channel不一样。

Channel中最常用的3个方法是map(), read()和write(). map()方法的方法签名为:MappedByteBuffer map(FileChannel.MapMode mode, long position, long size). 第一个参数执行映射时的模式,分别有只读/读写等模式,第二第三个参数用于控制将Channel的哪些数据映射成ByteBuffer。

packagecom.ivy.nio;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;importjava.nio.CharBuffer;importjava.nio.MappedByteBuffer;importjava.nio.channels.FileChannel;importjava.nio.charset.Charset;importjava.nio.charset.CharsetDecoder;public classFileChannelDemo {public static voidmain(String[] args) {//TODO Auto-generated method stub

File f= new File("./src/com/ivy/nio/FileChannelDemo.java");try(

FileChannel inChannel= newFileInputStream(f).getChannel();

FileChannel outChannel= new FileOutputStream("channelOutput.txt").getChannel()) {

MappedByteBuffer buffer= inChannel.map(FileChannel.MapMode.READ_ONLY, 0, f.length());

Charset charset= Charset.forName("GBK");

outChannel.write(buffer);

buffer.clear();

CharsetDecoder decoder=charset.newDecoder();

CharBuffer charBuffer=decoder.decode(buffer);

System.out.println(charBuffer);

}catch(IOException ioe) {

ioe.printStackTrace();

}

}

}

packagecom.ivy.nio;importjava.io.File;importjava.io.IOException;importjava.io.RandomAccessFile;importjava.nio.MappedByteBuffer;importjava.nio.channels.FileChannel;public classRandomFileChannelDemo {public static voidmain(String[] args) {//TODO Auto-generated method stub

File f= new File("channelOutput.txt");try(

RandomAccessFile raf= new RandomAccessFile(f, "rw");

FileChannel randomChannel=raf.getChannel();) {

MappedByteBuffer buffer= randomChannel.map(FileChannel.MapMode.READ_ONLY, 0, f.length());

randomChannel.position(f.length());

randomChannel.write(buffer);

}catch(IOException ioe) {

ioe.printStackTrace();

}

}

}

Charset

packagecom.ivy.nio;importjava.nio.ByteBuffer;importjava.nio.CharBuffer;importjava.nio.charset.Charset;importjava.nio.charset.CharsetDecoder;importjava.nio.charset.CharsetEncoder;public classCharsetTransformDemo {public static void main(String[] args) throwsException {//TODO Auto-generated method stub

Charset cn= Charset.forName("GBK");

CharsetEncoder cnEncoder=cn.newEncoder();

CharsetDecoder cnDecoder=cn.newDecoder();

CharBuffer cBuffer= CharBuffer.allocate(8);

cBuffer.put("孙");

cBuffer.put("悟");

cBuffer.put("空");

cBuffer.flip();

ByteBuffer bBuffer=cnEncoder.encode(cBuffer);for (int i = 0; i < bBuffer.capacity(); i++) {

System.out.print(bBuffer.get(i)+ " ");

}

System.out.println("\n" +cnDecoder.decode(bBuffer));

}

}

实际上,Charset类也提供了decode(ByteBuffer bb), encode(CharBuffer cb)和encode(String str),也就是说,获取了Charset对象后,如果仅仅需要进行简单的编码解码操作,其实无须创建CharsetEncoder & CharsetDecoder,直接调用Charst的encode和decode方法进行编码和解码就行。

文件锁

在NIO中,Java提供了FileLock来支持文件锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值