java io目录_Java -- 新IO -- 目录

20.1 Java 新IO简介

20.2 缓冲区与Buffer

例:演示缓冲区的操作流程

Class : IntBufferDemo01

20.2.2 深入缓冲区操作

20.2.3 创建子缓冲区

20.2.4 创建只读缓冲区

20.2.5 创建直接缓冲区

20.3 通道

20.3.1 FileChannel

例:使用输出通道输出内容

Class : FileChannelDemo01

packagelime.pri.limeNio._20_3_1.channeldemo;importjava.io.File;importjava.io.FileOutputStream;importjava.nio.ByteBuffer;importjava.nio.channels.FileChannel;public classFileChannelDemo01 {public static void main(String[] args) throwsException {

String info[]= {"lime","oracle","Lime","Oracle"};

File file= new File("F:/channels/out.txt");

FileOutputStream output= null;

output= newFileOutputStream(file);

FileChannel fout= null;

fout=output.getChannel();

ByteBuffer buf= ByteBuffer.allocate(1024);for(int i = 0;i < info.length;i++){

buf.put(info[i].getBytes());

buf.put("\n".getBytes());

}

buf.flip();

fout.write(buf);

fout.close();

output.close();

}

}

例:使用通道进行读写操作

Class :FileChannelDemo02

packagelime.pri.limeNio._20_3_1.channeldemo;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.nio.ByteBuffer;importjava.nio.channels.FileChannel;public classFileChannelDemo02 {public static void main(String[] args) throwsException {

File file1= new File("F:/channels/note.txt");

File file2= new File("F:/channels/outnote.txt");

FileInputStream input= null;

FileOutputStream output= null;

input= newFileInputStream(file1);

output= newFileOutputStream(file2);

FileChannel fin= null;

FileChannel fout= null;

fin=input.getChannel();

fout=output.getChannel();

ByteBuffer buf= ByteBuffer.allocate(1024);int temp = 0;while((temp = fin.read(buf)) != -1){

buf.flip();

fout.write(buf);

buf.clear();

}

fin.close();

fout.close();

input.close();

output.close();

}

}

20.3.2 内存映射

内存映射可以把文件映射到内存中,这样文件内的数据就可以用内存读/写指令来访问,而不是用InputStream或OutputStream这样的I/O操作类,采用此种方式读取文件的速度是最快的。

提示:Java中访问文件内容的4中方法。

⊙ RandomAccessFile,随机读取数据,此种访问速度较慢。

⊙ FileInputStream,文件输入流,使用此种方式数度较慢。

⊙ 缓冲读取(例BufferedReader),使用此种方式访问速度较快。

⊙ 内存映射(MappedByteBuffer),使用此种方式读取速度最快。

例:内存映射

Class : FileChannelDemo03

packagelime.pri.limeNio._20_3_2.channeldemo;importjava.io.File;importjava.io.FileInputStream;importjava.nio.MappedByteBuffer;importjava.nio.channels.FileChannel;public classFileChannelDemo03 {public static void main(String[] args) throwsException {

File file= new File("F:/channels/mappedByteBuffer.txt");

FileInputStream input= null;

input= newFileInputStream(file);

FileChannel fin= null;

fin=input.getChannel();

MappedByteBuffer mbb= null;

mbb= fin.map(FileChannel.MapMode.READ_ONLY, 0, file.length());byte data[] = new byte[(int)file.length()];int foot = 0;while(mbb.hasRemaining()){

data[foot++] =mbb.get();

}

System.out.println(newString(data));

fin.close();

input.close();

}

}

20.4 文件锁:FileLock

在Java新IO中提供了文件锁的功能,这样当一个线程将文件锁定之后,其他线程是无法操作此文件的。要想进行文件的锁定操作,则要使用FileLock类完成,此类的对象需要依靠FileChannel进行实例化操作。

⊙ 共享锁:允许多个线程进行文件的读取操作。

⊙ 独占锁:只允许一个线程进行文件的读/写操作。

例:将文件锁定

Class : FileLockDemo

packagelime.pri.limeNio._20_4.channeldemo;importjava.io.File;importjava.io.FileOutputStream;importjava.nio.channels.FileChannel;importjava.nio.channels.FileLock;public classFileLockDemo {public static void main(String[] args) throwsException {

File file= new File("F:/channels/fileLock.txt");

FileOutputStream output= null;

output= new FileOutputStream(file,true);

FileChannel fout= null;

fout=output.getChannel();

FileLock lock=fout.tryLock();if(lock != null){

System.out.println(file.getName()+ " 文件锁定300秒");

Thread.sleep(300000);

lock.release();

System.out.println(file.getName()+ " 文件解除锁定");

}

fout.close();

output.close();

}

}

20.5 字符集:Charset

例:取得Charset类的全部编码

Class : GetAllCharsetDemo

packagelime.pri.limeNio._20_5.channeldemo;importjava.nio.charset.Charset;importjava.util.Iterator;importjava.util.Map;importjava.util.SortedMap;public classGetAllCharsetDemo {public static voidmain(String[] args) {

SortedMap all = null;

all=Charset.availableCharsets();

Iterator> iter = null;

iter=all.entrySet().iterator();while(iter.hasNext()){

Map.Entry me =iter.next();

System.out.println(me.getKey()+ " --> " +me.getValue());

}

}

}

例:编码-解码操作

Class : CharsetEnDeDemo

20.6 Selector

在新IO中Selector是一个极其重要的概念,在原来使用IO和Socket构造网络服务时,所有的网络服务经使用阻塞方式进行客户端的连接,而如果使用了新IO则可以构造一个非阻塞的的网络服务。

Selector类的常用方法:

⊙ public static Selector open() throws IOException :  打开一个选择器。

⊙ public abstract int select() throws IOException : 选择一组键,其相应的通道已为 I/O 操作准备就绪。

⊙ public abstract Set selectedKeys() : 返回此选择器的已选择键集。

在进行非阻塞网络开发时需要使用SelectableChannel类向Select类注册,而且在新IO中实现网络程序需要依靠ServerSocketChannel类与SocketChannel类,这两个类都是SelectableChannel的子类,SelectableChannel提供了注册Selector的方法和阻塞模式。

ServerSocketChannel类的常用方法:

⊙ public final SelectableChannel configureBlocking(boolean block) throws IOException : 调整此通道的阻塞模式。true:阻塞模式;false:非阻塞模式

⊙ public final SelectionKey register(Selector sel, int ops) throws ClosedChannelException :  向给定的选择器注册此通道,返回一个选择键。

⊙ public static ServerSocketChannel open() throws IOException : 打开服务器的套接字通道。

⊙ public abstract ServerSocket socket() : 返回与此通道关联的服务器套接字。

在使用register()方法时需要指定一个选择器(Selector对象)以及Select域,Selector对象可以通过Selector中的open()方法取得,而Selector域则在SelectionKey类中定义。

4中Selector域:

⊙ public static final int OP_ACCEPT   = 1 << 4: 相当于ServerSocket中的accpet()操作。

⊙ public static final int OP_CONNECT  = 1 << 3 :连接操作。

⊙ public static final int OP_READ = 1 << 0 : 读操作。

⊙ public static final int OP_WRITE = 1 << 2 : 写操作。

如果要使用服务器想客户端发送信息,则需要通过SelectionKey类中提供的方法判断服务器的操作状态。而要想取得客户端的连接也需要使用SelectionKey类。

SelectionKey常用的方法:

⊙ public abstract SelectableChannel channel() : 返回为之创建此键的通道。

⊙ public final boolean isAcceptable() : 测试此键的通道是否已准备好接受新的套接字连接。

⊙ public final boolean isConnectable() : 测试此键的通道是否已完成其套接字连接操作。

⊙ public final boolean isReadable() : 测试此键的通道是否已准备好进行读取。

⊙ public final boolean isWritable() : 测试此键的通道是否已准备好进行写入。

例:取得时间的服务器

Class : DateServer

packagelime.pri.limeNio._20_6.channeldemo.selector;importjava.net.InetSocketAddress;importjava.net.ServerSocket;importjava.nio.ByteBuffer;importjava.nio.channels.SelectionKey;importjava.nio.channels.Selector;importjava.nio.channels.ServerSocketChannel;importjava.nio.channels.SocketChannel;importjava.util.Date;importjava.util.Iterator;importjava.util.Set;public classDateServer {public static void main(String[] args) throwsException {int ports[] = {8000,8001,8002,8003,8005,8006}; //定义一组连接端口号

Selector selector = Selector.open(); //打开一个选择器

for(int i = 0;i < ports.length;i++){ //构造服务器的启动信息

ServerSocketChannel initSer = null; //声明ServerSocketChannel

initSer = ServerSocketChannel.open(); //打开服务器套接字通道

initSer.configureBlocking(false); //服务器配置为非阻塞

ServerSocket initSock = initSer.socket(); //检索此通道关联的服务器套接字

InetSocketAddress address = null; //表示监听地址

address = new InetSocketAddress(ports[i]); //实例化绑定地址

initSock.bind(address); //绑定地址//注册选择器,相当于使用accept()方法接收

initSer.register(selector, SelectionKey.OP_ACCEPT);

System.out.println("服务器运行,在 " + ports[i] + " 端口监听。");

}int keysAdd = 0; //接收一组SelectionKey

while((keysAdd = selector.select()) > 0){ //选择一组键,相应的通道已为IO准备就绪

Set selectedkeys = selector.selectedKeys(); //取出全部生成的key

Iterator iter = selectedkeys.iterator(); //实例化Iterator

while(iter.hasNext()){ //迭代全部的key

SelectionKey key = (SelectionKey)iter.next(); //取出每一个SelectionKey

if(key.isAcceptable()){ //判断客户端是否已经连接上

ServerSocketChannel server = (ServerSocketChannel)key.channel(); //取得Channel

SocketChannel client = server.accept(); //接收新连接

client.configureBlocking(false); //设置成非阻塞状态

ByteBuffer outBuf = ByteBuffer.allocateDirect(1024); //开辟缓冲区

outBuf.put(("当前时间为:" + new Date()).getBytes()); //缓冲区设置内容

outBuf.flip(); //重置缓冲区

client.write(outBuf); //输出信息

client.close(); //关闭输出流

}

}

selectedkeys.clear();//清除全部key

}

}

}

Console : telnet

013654ff6da8fbb9acc53eea5dba35f1.png

b52e459b08d47db9fbcadbee4e93df9c.png

啦啦啦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值