1.Buffered缓冲技术基本概述
position,limit,capacity三个变量完成了缓冲区的操作代码
position:表示下一个缓冲区读取或写入的操作指针,每向缓冲区中写入数据的时候此指针就会改变,指针永远放倒写入的最后一个元素之后。即:如果写入了4个位置的数据,则position会指向第5个位置。
limit:表示还有多少数据需要存储或读取,position<=limit。
capacity:表示缓冲区的最大容量,limit<=capacity。此值在分配缓冲区时被设置,一般不会改变。
public class NewIOBufferDemo {
public static void main(String[] args) {
IntBuffer buf=IntBuffer.allocate(10);
System.out.println("1、写入数据之前的position,limit,capacity");
System.out.println("positon:"+buf.position()+" limit:"+buf.limit()+" capacity:"+buf.capacity());
int [] temp= {1,4,5};
buf.put(3);//buf缓冲区内存放了1个数据
buf.put(temp);//buf缓冲区内存放了3个数据,共计4个
System.out.println("2、写入数据之后的position,limit,capacity");
System.out.println("positon:"+buf.position()+" limit:"+buf.limit()+" capacity:"+buf.capacity());
buf.flip();//重设缓冲区,positon=0,limit=原本position
System.out.println("3、准备输出数据时的position,limit,capacity");
System.out.println("positon:"+buf.position()+" limit:"+buf.limit()+" capacity:"+buf.capacity());
System.out.println("缓冲区内的内容");
while (buf.hasRemaining()) {
int x=buf.get();
System.out.println(x);
}
}
}
结果:
1、写入数据之前的position,limit,capacity
positon:0 limit:10 capacity:10
2、写入数据之后的position,limit,capacity
positon:4 limit:10 capacity:10
3、准备输出数据时的position,limit,capacity
positon:0 limit:4 capacity:10
缓冲区内的内容
3
1
4
5
2.创建子缓冲区
public class NewIOBufferDemo {
public static void main(String[] args) {
IntBuffer buf=IntBuffer.allocate(10);
IntBuffer suf=null;
for (int i = 0; i < 10; i++) {
buf.put(2*i+1);//在主缓冲区中加入10个奇数
}
//通过slice()创建子缓冲区
buf.position(2);
buf.limit(6);
suf=buf.slice();
for (int i = 0; i < suf.capacity(); i++) {
int temp=suf.get(i);
suf.put(temp-1);
}
buf.flip();//重设缓冲区,positon=0,limit=原本position
buf.limit(buf.capacity());
System.out.println("主缓冲区内的内容");
while (buf.hasRemaining()) {
int x=buf.get();
System.out.println(x);
}
}
}
结果:
主缓冲区内的内容
1
3
4
6
8
10
13
15
17
19
3.创建只读缓冲区
public class NewIOBufferDemo {
public static void main(String[] args) {
IntBuffer buf=IntBuffer.allocate(10);
IntBuffer read=null;
for (int i = 0; i < 10; i++) {
buf.put(2*i+1);//在主缓冲区中加入10个奇数
}
read=buf.asReadOnlyBuffer();//创建只读缓冲区
read.flip();//重设缓冲区,positon=0,limit=原本position
buf.limit(buf.capacity());
System.out.println("主缓冲区内的内容");
while (read.hasRemaining()) {
int x=read.get();
System.out.println(x);
}
//read.put(5); //由于是只读,该语句将导致错误
}
}
结果:
主缓冲区内的内容
1
3
5
7
9
11
13
15
17
19
3.创建直接缓冲区
直接缓冲区能稍微提高一下性能
public class NewIOBufferDemo {
public static void main(String[] args) {
ByteBuffer buf=ByteBuffer.allocateDirect(10);
byte[] temp= {1,3,5,7,9,};
buf.put(temp);//设置一组内容
buf.flip();//重设缓冲区,positon=0,limit=原本position
System.out.println("主缓冲区内的内容");
while (buf.hasRemaining()) {
int x=buf.get();
System.out.println(x);
}
}
}
结果:
主缓冲区内的内容
1
3
5
7
9
4.通道写入文件流
类似于输入和输出流,但通道是双向的,即可以input也可以output。也是利用缓冲区技术
public class NewIOBufferDemo {
public static void main(String[] args) throws IOException {
String info[]= {"清华大学","北京大学","北京理工大学","北京师范大学","中央财经大学"};
File file=new File("d:"+File.separator+"out.txt");
FileOutputStream outputStream=null;
outputStream=new FileOutputStream(file);
FileChannel fileChannelOut=null;//创建文件通道对象
fileChannelOut=outputStream.getChannel();//得到输出文件通道
ByteBuffer buffer=ByteBuffer.allocate(1024);
for (int i = 0; i < info.length; i++) {
buffer.put(info[i].getBytes());
}
buffer.flip();//重建缓冲器
fileChannelOut.write(buffer);//输出缓冲区的内容
fileChannelOut.close();
outputStream.close();
}
}
结果:
d盘下创建out.text
文件内容
清华大学北京大学北京理工大学北京师范大学中央财经大学
5.通道输出文件流(双向输入输出)
public class NewIOBufferDemo {
public static void main(String[] args) throws IOException {
File file1=new File("d:"+File.separator+"out.txt");
File file2=new File("d:"+File.separator+"out2.txt");
FileInputStream inputStream=null;
FileOutputStream outputStream=null;
outputStream=new FileOutputStream(file2);
inputStream=new FileInputStream(file1);
FileChannel fileChannelOut=null;//创建文件通道对象
FileChannel fileChannelIn=null;//创建文件通道对象
fileChannelOut=outputStream.getChannel();//得到输出文件通道
fileChannelIn=inputStream.getChannel();//得到输入文件通道
ByteBuffer buffer=ByteBuffer.allocate(1024);
int temp=0;
while ((temp=fileChannelIn.read(buffer))!=-1) {
buffer.flip();
fileChannelOut.write(buffer);
buffer.clear();//清空缓冲区,所有的状态变量的位置恢复到原点
}
fileChannelIn.close();
fileChannelOut.close();
inputStream.close();
outputStream.close();
}
}
结果:
d盘下创建out2.text
文件内容
清华大学北京大学北京理工大学北京师范大学中央财经大学
6.内存映射
MapedByteBuffer,读写速度较快
3种绑定形式
public class NewIOBufferDemo {
public static void main(String[] args) throws IOException {
File file1=new File("d:"+File.separator+"out.txt");
FileInputStream inputStream=null;
inputStream=new FileInputStream(file1);
FileChannel fileChannelIn=null;//创建文件通道对象
fileChannelIn=inputStream.getChannel();//得到输入文件通道
MappedByteBuffer mapBuffer=null;
mapBuffer=fileChannelIn.map(FileChannel.MapMode.READ_ONLY,0, file1.length());
byte data[]=new byte[(int)file1.length()];
int foot=0;
while(mapBuffer.hasRemaining()) {
data[foot++]=mapBuffer.get();//读取数据
}
System.out.println(new String(data) );
fileChannelIn.close();
inputStream.close();
}
}
结果:
清华大学北京大学北京理工大学北京师范大学中央财经大学
7.文件锁
FileLock类
共享锁:允许多个线程进行文件的读取操作
独占锁:只允许一个线程进行文件的读/写操作
public class NewIOBufferDemo {
public static void main(String[] args) throws IOException, InterruptedException {
File file=new File("d:"+File.separator+"out2.txt");
FileOutputStream fileOutputStream=null;
fileOutputStream=new FileOutputStream(file,true);
FileChannel fileChannelOut=null;//创建文件通道对象
fileChannelOut=fileOutputStream.getChannel();//得到输入文件通道
FileLock lock=fileChannelOut.tryLock();//独占锁操作
if (lock!=null) {
System.out.println(file.getName()+"文件锁定10秒");
Thread.sleep(10000);
lock.release();//释放
System.out.println("文件解除锁定");
}
fileChannelOut.close();
fileOutputStream.close();
}
}
结果
out2.txt文件锁定5秒
经过漫长的五秒钟
文件解除锁定
8.字符集CharSet类
CharSet类,CharsetEncoder类
public class NewIOBufferDemo {
public static void main(String[] args) throws IOException, InterruptedException {
SortedMap<String, Charset> allMap=null;
allMap=Charset.availableCharsets();
Iterator< Map.Entry<String, Charset>> iterator=null;
iterator=allMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Charset>me=iterator.next();
System.out.println(me.getKey()+">>>>"+me.getValue());
}
}
}
结果:
Big5>>>>Big5
Big5-HKSCS>>>>Big5-HKSCS
CESU-8>>>>CESU-8
EUC-JP>>>>EUC-JP
EUC-KR>>>>EUC-KR
GB18030>>>>GB18030
GB2312>>>>GB2312
GBK>>>>GBK
更多未显示
9.字符集编解码
public class NewIOBufferDemo {
public static void main(String[] args) throws IOException, InterruptedException {
Charset latin1=Charset.forName("UTF-8");
CharsetEncoder encoder=latin1.newEncoder();//得到编码器
CharsetDecoder decoder=latin1.newDecoder();//得到解码器
//通过CharBuffer类中的
CharBuffer cb=CharBuffer.wrap("中央广播电视大学");
ByteBuffer buffer=encoder.encode(cb);//进行编码操作
System.out.println(decoder.decode(buffer));//进行解码操作
}
}
结果:
中央广播电视大学
10.selector构建异步非阻塞服务器
使用ServerSocketChannel类与SocketChannel类
实际开发中较少,但是能改善服务器性能
public class NewIOBufferDemo {
public static void main(String[] args) throws IOException, InterruptedException {
int ports [] = {8000,8001,8002,8003,8005,8006};//表示5个监听端口
Selector selector=Selector.open();//通过open()方法找到Selector
for (int i = 0; i < ports.length; i++) {
ServerSocketChannel initser=null;
initser=ServerSocketChannel.open();//打开服务器通道
initser.configureBlocking(false);//设置服务器为非阻塞状态
ServerSocket initSock=initser.socket();
InetSocketAddress address=null;
address=new InetSocketAddress(ports[i]);//实例化绑定地址
initSock.bind(address);//进行服务的绑定
initser.register(selector, SelectionKey.OP_ACCEPT);//等待连接
System.out.println("服务器运行在"+ports[i]+"端口监听");
}
//要接受全部生成的key,并通过连接进行判断是否获取客户端的输出
int keysAdd=0;
while ((keysAdd=selector.select())>0) {//选择一组建,并且相应的通道已经就绪
Set<SelectionKey> selectionKeys=selector.selectedKeys();//取出全部selectKey键值
Iterator<SelectionKey> iterator=selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key=iterator.next();
if (key.isAcceptable()) {
ServerSocketChannel server=(ServerSocketChannel) key.channel();
SocketChannel client=server.accept();//接受新连接
client.configureBlocking(false);//配置为非阻塞
ByteBuffer outBuffer=ByteBuffer.allocateDirect(1024);
outBuffer.put(("当前时间为:"+new Date()).getBytes());
outBuffer.flip();
client.write(outBuffer);
client.close();
}
}
selectionKeys.clear();//清除全部key
}
}
}