java的io操作

最近在做一个日志组件,考虑到性能和日志的完整性,使用了MMAP,即内存映射的方式写日志,顺便总结一下Java里面的IO操作.

1.IO

IO是阻塞性的,效率不高,但是很容易理解
可以想像成是一个水管,水管里面有空位才能往里写,否则就要等待, 水管里面有水才能读,否则也只能等待.不管IO怎么包装,其操作都是针对字节的.

private static void testIO()throws Exception{
    File file = new File("test.txt");
    //写
    FileOutputStream fileOutputStream = new FileOutputStream(file);
    byte[] bytes = "hello world".getBytes();
    fileOutputStream.write(bytes);
    fileOutputStream.close();

    //读
    FileInputStream fileInputStream = new FileInputStream(file);
    byte[] buffer = new byte[1024];
    fileInputStream.read(buffer);
    fileInputStream.close();
}

2.NIO

NIO的操作是针对buffer的,且是非阻塞的,因此效率要比IO高.
其中的核心是selector , 一个selector可以监听多个channel , 当每个channel当中有事件产生时,
便会出发selector的事件

//服务端
private static void testNIO_Server() throws Exception{
    Selector selector = Selector.open();
    ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    serverSocketChannel.bind(new InetSocketAddress("127.0.0.1",8000));
    serverSocketChannel.configureBlocking(false).register(selector, SelectionKey.OP_ACCEPT);

    ByteBuffer readBuff = ByteBuffer.allocate(1024);
    ByteBuffer writeBuff = ByteBuffer.allocate(1024);
    writeBuff.put("recived it !".getBytes());
    writeBuff.flip();

    while(true){
        int nReady = selector.select();
        if(nReady <= 0){
            continue;
        }
        Set<SelectionKey> keys = selector.selectedKeys();
        Iterator iterator = keys.iterator();
        while(iterator.hasNext()){
            SelectionKey selectionKey = (SelectionKey) iterator.next();
            iterator.remove();
            if(selectionKey.isAcceptable()){
                //创建新的连接,并监听read和write事件
                SocketChannel socketChannel= serverSocketChannel.accept();
                socketChannel.configureBlocking(false).register(selector,SelectionKey.OP_READ);
            }else if(selectionKey.isReadable()){
                //read事件
                readBuff.clear();
                SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                socketChannel.read(readBuff);
                readBuff.flip();
                System.out.println("服务端收到的:"+new String(readBuff.array()));
                selectionKey.interestOps(SelectionKey.OP_WRITE);
            }else if(selectionKey.isWritable()){
                //write事件
                SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                socketChannel.write(writeBuff);
                selectionKey.interestOps(SelectionKey.OP_READ);
            }
        }
    }
}

//客户端
private static void testNIO_Client()throws Exception{
    ByteBuffer writeBuffer = ByteBuffer.allocate(128);
    writeBuffer.put("hello".getBytes());
    writeBuffer.flip();
    SocketChannel ssc = SocketChannel.open();
    boolean connectResult = ssc.connect(new InetSocketAddress("127.0.0.1",8000));
    ssc.write(writeBuffer);
}

3.MMAP

MMAP是内存映射,将磁盘上的空间映射到内存当中,性能接近于直接写内存,而且由系统保证能将内存当中的内容写入到磁盘.
MMAP需要事先指定大小,然后往里面进行读写操作.

public static void testMMAP() throws Exception{
    File mmapFile = new File("test.txt");
    MappedByteBuffer mappedByteBuffer = new RandomAccessFile(mmapFile.getAbsolutePath(), "rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, mmapFile.length());
    byte[] bytes = "hello world".getBytes();
    mappedByteBuffer.put(bytes);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值