读书人

分布式服务框架之NIO(1)

发布时间: 2012-10-16 09:57:37 作者: rapoo

分布式服务框架之NIO(一)

??? NIO在实现分布式服务框架中非阻塞高并发的服务器端功能十分有用。抽空学了下,下面的学习过程中接触到的代码示例,这些代码基本演示了NIO的最基本的一些特性。

??

??? (一)Buffer:

???? 代码一:演示直接缓冲区的使用

??

import java.nio.ByteBuffer;public class ByteBufferDemo01 {    public static void main(String[] args) {        //直接缓冲区        ByteBuffer buf = ByteBuffer.allocateDirect(10);        byte temp[] = { 1, 2, 3 };        buf.put(temp);        buf.flip();        System.out.print("主缓冲区中的内容:");        while (buf.hasRemaining()) {            int x = buf.get();            System.out.print(x + "、");        }    }}

?

??? 代码二:演示缓冲区的基本使用

???

import java.nio.IntBuffer;public class IntBufferDemo01 {    public static void main(String[] args) {        // 准备出10个大小的缓冲区        IntBuffer buf = IntBuffer.allocate(10);        System.out.print("1、写入数据之前的position、limit和capacity:");        System.out.println("position = " + buf.position() + ",limit = " + buf.limit()                           + ",capacty = " + buf.capacity());        int temp[] = { 1, 2, 3 };        buf.put(5);        buf.put(temp);        System.out.print("2、写入数据之后的position、limit和capacity:");        System.out.println("position = " + buf.position() + ",limit = " + buf.limit()                           + ",capacty = " + buf.capacity());        System.out.println();        //重设缓冲区        buf.flip();        System.out.print("3、准备输出数据时的position、limit和capacity:");        System.out.println("position = " + buf.position() + ",limit = " + buf.limit()                           + ",capacty = " + buf.capacity());        System.out.print("缓冲区中的内容:");        while (buf.hasRemaining()) {            int x = buf.get();            System.out.print(x + "、");        }    }}

?

?? 代码三:子缓冲区的使用

??

import java.nio.IntBuffer;public class IntBufferDemo02 {    public static void main(String[] args) {        //创建缓冲区,并初始化        IntBuffer buf = IntBuffer.allocate(10);        IntBuffer sub = null;        for (int i = 0; i < 10; i++) {            buf.put(i * 2 + 1);        }        //需要通过slice() 创建子缓冲区,可通过子缓冲区修改主缓冲区内容        buf.position(2);        buf.limit(6);        sub = buf.slice();        for (int i = 0; i < sub.capacity(); i++) {            int temp = sub.get(i);            sub.put(temp - 1);        }        //重设缓冲区        buf.flip();        buf.limit(buf.capacity());        System.out.print("主缓冲区中的内容:");        while (buf.hasRemaining()) {            int x = buf.get();            System.out.print(x + " 、");        }    }}

?

?? 代码四:只读缓冲区

??

import java.nio.IntBuffer;public class IntBufferDemo03 {    public static void main(String[] args) {        //准备出10个大小的缓冲区,并初始化        IntBuffer buf = IntBuffer.allocate(10);        IntBuffer read = null;        for (int i = 0; i < 10; i++) {            buf.put(2 * i + 1);        }                // 创建只读缓冲区        read = buf.asReadOnlyBuffer();        // 重设缓冲区        read.flip();        System.out.print("主缓冲区中的内容:");        while (read.hasRemaining()) {            int x = read.get();            System.out.print(x + "、");        }                //修改,错误       // read.put(30) ;      }}

?

?

?

?

?

?? (二)Channel

?

?? 代码一:通道写入文件

???

import java.io.File;import java.io.FileOutputStream;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;public class FileChannelDemo01 {    public static void main(String[] args) throws Throwable {        //初始化        String infos[] = { "test1", "test2", "test3" };        FileOutputStream output = new FileOutputStream("D:" + File.separator + "out.txt");        //读取        FileChannel fout = output.getChannel();        ByteBuffer buf = ByteBuffer.allocate(1024);        for (String info : infos) {            buf.put(info.getBytes());        }        //重设缓冲区(非常重要)        buf.flip();        //写入        fout.write(buf);        fout.close();        output.close();    }}

?

? 代码二:通道的双向性,可读和可写

?

import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;public class FileChannelDemo02 {    /**     * 通道是双向的,可读,可写     *      * @param args     * @throws Throwable     */    public static void main(String[] args) throws Throwable {        File file1 = new File("d:" + File.separator + "out.txt");        File file2 = new File("d:" + File.separator + "in.txt");        FileInputStream input = null;        FileOutputStream output = null;        output = new FileOutputStream(file2);        input = new FileInputStream(file1);        FileChannel fout = output.getChannel();        FileChannel fin = input.getChannel();        ByteBuffer buf = ByteBuffer.allocate(1024);        while ((fin.read(buf)) != -1) {            buf.flip();            fout.write(buf);            buf.clear();        }        fin.close();        fout.close();        output.close();    }}

?

? 代码三:MappedByteBuffer的使用

??

import java.io.File;import java.io.FileInputStream;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel;public class FileChannelDemo03 {    public static void main(String[] args) throws Throwable {        File file = new File("d:" + File.separator + "mldn.txt");        FileInputStream input = null;        input = new FileInputStream(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(new String(data)); // 输出内容        fin.close();        input.close();    }}

??

?

???

?? (三)Charset

??? 代码一:编码和解码

???

import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.charset.Charset;import java.nio.charset.CharsetDecoder;import java.nio.charset.CharsetEncoder;public class CharsetEnDeDemo {    /**     * 编码和解码操作     * @param args     */    public static void main(String[] args) throws Throwable{        Charset utf=Charset.forName("UTF-8");        //得到编码器和解码器        CharsetEncoder encoder=utf.newEncoder();        CharsetDecoder decoder=utf.newDecoder();                CharBuffer cb=CharBuffer.wrap("NIO可以用来构建高性能服务器");        //编码和解码        ByteBuffer buf=encoder.encode(cb);        System.out.println(decoder.decode(buf));    }

?

? 代码二:获取全部可用的字符集

?

import java.nio.charset.Charset;import java.util.Map;import java.util.SortedMap;public class GetAllCharsetDemo {    public static void main(String[] args) {        //得到全部可用的字符集        SortedMap<String, Charset> all = Charset.availableCharsets();        for (Map.Entry<String, Charset> entry : all.entrySet()) {            System.out.println(entry.getKey() + " --->" + entry.getValue());        }    }}

?

??

?? (四)FileLock

??? 代码一:文件独占锁的使用

????

import java.io.File;import java.io.FileOutputStream;import java.nio.channels.FileChannel;import java.nio.channels.FileLock;public class FileLockDemo {    public static void main(String[] args) throws Throwable {        File file = new File("d:" + File.separator + "out.txt");        FileOutputStream output = null;        output = new FileOutputStream(file, true);        FileChannel fout = output.getChannel();        FileLock lock = fout.tryLock();        if (lock != null) {            System.out.println(file.getName() + "文件锁定30秒");            Thread.sleep(30000);            lock.release();            System.out.println(file.getName() + "文件解除锁定");        }        fout.close();        output.close();    }}

?

??

???(五)selector

????代码一:无阻塞服务端代码示例

???

import java.net.InetSocketAddress;import java.net.ServerSocket;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.util.Date;import java.util.Iterator;import java.util.Set;public class DataServer {    /**     *      * @param args     */    public static void main(String[] args) throws Throwable {        int ports[] = { 8000, 8001, 8002, 8003, 8005, 8006 }; // 表示五个监听端口        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> selectedKeys = selector.selectedKeys();// 取出全部生成的key            Iterator<SelectionKey> iter = selectedKeys.iterator();            while (iter.hasNext()) {                SelectionKey key = iter.next(); // 取出每一个key                if (key.isAcceptable()) {                    ServerSocketChannel server = (ServerSocketChannel) key.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        }    }}

?

?

读书人网 >编程

热点推荐