Java 杂谈

Java IO介绍

2019-03-30  本文已影响2人  SevenLin1993

Java IO介绍

Java IO主要是指的是java.iojava.nio两个包下提供的对IO操作的功能(由于网络通信也是一种IO,所以也会是Java IO的范畴之中),主要包括:

IO模型分类

IO模型是通用的,一般主要分类如下

同步

同步IO模型主要分阻塞IO(blocking IO)和非阻塞IO(non-blocking IO),如下:

▪ 同步阻塞IO

即同步阻塞IO,线程会被操作系统挂起,如java.io基于流模型的IO,也就是常说的BIO

▪ 非阻塞IO

即同步非阻塞IO,线程不被操作系统挂起,如java.nio包下基于多路复用,同步非阻塞的IO实现,也就是常说的NIO

异步IO

异步IO模型,调用者发起一个请求,然后立即做其他的事情,通过信号通知或者回调来告知调用者,如java.nio下关于Asynchronous的相关实现

Java IO Stream

image.png

主要分针对二进制操作的字节流和针对读取文本信息的字符流两大块

我们知道,Java IO整个模型操作都是基于装饰者模式,也就是说其实所有的IO实现都是基于(InputStream/OutputStream),不用的实现用于解决不同的问题,例如:

Sample

try (InputStream in = IODemo.class.getClassLoader().getResourceAsStream("file/demo.json")) {
    StringBuilder content = new StringBuilder();
    byte[] buffer = new byte[1024];
    int i;
    while ((i = in.read(buffer)) > 0) {
        content.append(new String(buffer, 0, i, StandardCharsets.UTF_8));
    }
    System.out.println(content.toString());

} catch (IOException e) {
    e.printStackTrace();
}
try (InputStream in = IODemo.class.getClassLoader().getResourceAsStream("file/demo.json");
    FileOutputStream out = new FileOutputStream("/Users/sevenlin/demo.json")) {

    byte[] buffer = new byte[1024];
    int i;
    while ((i=in.read(buffer))>0){
        out.write(buffer,0,i);
    }

} catch (IOException e) {
    e.printStackTrace();
}

Java NIO

Java NIO 是一种同步非阻塞IO的实现,并且底层通过操作系统的多路复用IO机制实现,目的是为了提高IO性能,不同操作系统有不同的实现,如Linux通过epoll,而windows则通过IOCP,mac通过poll

主要概念如下:

Sample

String path = NioDemo.class.getClassLoader().getResource("file/demo.json").getPath();

try (FileChannel channel = new FileInputStream(path).getChannel()) {
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    StringBuilder content = new StringBuilder();
    while (channel.read(buffer) > 0) {
        buffer.flip();
        content.append(new String(buffer.array(), 0, buffer.limit(), StandardCharsets.UTF_8));
        buffer.clear();
    }
    System.out.println(content.toString());
} catch (IOException e) {
    e.printStackTrace();
}
String path = NioDemo.class.getClassLoader().getResource("file/demo.json").getPath();

try (FileChannel in = new FileInputStream(path).getChannel();
    FileChannel out = new FileOutputStream("/Users/sevenlin/demo.json").getChannel()) {
    for (long limit = in.size();limit>0;){
        long transferred = in.transferTo(in.position(), in.size(), out);
        limit -= transferred;
    }
} catch (IOException e) {
    e.printStackTrace();
}
public class NioServer {

    public static void main(String[] args) throws Exception {

        // 声明ServerSocket
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(8088));
        serverSocketChannel.configureBlocking(false);

        // 注册Select
        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            // 同步等待
            selector.select();
            selector.selectedKeys().forEach(key -> {
                try (SocketChannel c = ((ServerSocketChannel)key.channel()).accept()) {
                    c.write(Charset.defaultCharset().encode("Hello World"));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });

        }

    }

    public static class Client {
        public static void main(String[] args) {

            for (int i = 0; i < 10; i++) {
                new Thread(() -> {
                    try (Socket socket = new Socket(InetAddress.getLocalHost(), 8088)) {

                        InputStream in = socket.getInputStream();
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
                        bufferedReader.lines().forEach(System.out::println);

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }).start();
            }

        }
    }

}

Java NIO2(AIO)

异步IO模型主要通过两种方式实现读写操作结果的处理

URL resource = AioDemo.class.getClassLoader().getResource("file/demo.json");
Path path = Paths.get(resource.toURI());

ByteBuffer buffer = ByteBuffer.allocate(1024);
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path);

Future<Integer> future = channel.read(buffer, 0);

future.get();//wait

if(future.isDone()){
    buffer.flip();
    System.out.println(new String(buffer.array(),buffer.position(),buffer.limit()));
    buffer.clear();
}
URL resource = AioDemo.class.getClassLoader().getResource("file/demo.json");
Path path = Paths.get(resource.toURI());

ByteBuffer buffer = ByteBuffer.allocate(1024);
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path);

channel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
    @Override
    public void completed(Integer result, ByteBuffer attachment) {
        buffer.flip();
        System.out.println(new String(buffer.array(),buffer.position(),buffer.limit()));
        buffer.clear();
    }

    @Override
    public void failed(Throwable exc, ByteBuffer attachment) {
        exc.printStackTrace();
    }
});

//wait for done
Thread.currentThread().join();

对比

参考

上一篇 下一篇

猜你喜欢

热点阅读