zoukankan      html  css  js  c++  java
  • 十七、Java NIO AsynchronousFileChannel

    所有文章

    https://www.cnblogs.com/lay2017/p/12901123.html

    正文

    在Java7的时候,加入了AsynchronousFileChannel,使得你可以进行异步地read或write操作。本文关于如何使用AsynchronousFileChannel。

    创建一个AsynchronousFileChannel

    Path path = Paths.get("data/test.xml");
    
    AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);

    读取数据

    读取数据有两种方式

    通过Future读取

    通过read获取Future,read方法会立即返回

    Future<Integer> operation = fileChannel.read(buffer, 0);

    下面是一个完整示例

    AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);
    
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    long position = 0;
    
    Future<Integer> operation = fileChannel.read(buffer, position);
    
    while(!operation.isDone());
    
    buffer.flip();
    byte[] data = new byte[buffer.limit()];
    buffer.get(data);
    System.out.println(new String(data));
    buffer.clear();

    示例中read直接返回了Future,通过Future不断轮询是否完成。完成以后,数据已经进入buffer。再从buffer读取数据并打印

    通过CompletionHandler

    除了通过Future主动轮询之外,还可以通过CompletionHandler接口的回调处理,示例代码如下

    fileChannel.read(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() {
        @Override
        public void completed(Integer result, ByteBuffer attachment) {
            System.out.println("result = " + result);
    
            attachment.flip();
            byte[] data = new byte[attachment.limit()];
            attachment.get(data);
            System.out.println(new String(data));
            attachment.clear();
        }
    
        @Override
        public void failed(Throwable exc, ByteBuffer attachment) {
    
        }
    });

    我们看到,completed在正常回调的时候触发。failed回调在失败的时候触发

    写入数据

    与读取数据类似,写入数据同样支持两种方式

    通过Future写入

    Path path = Paths.get("data/test-write.txt");
    AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);
    
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    long position = 0;
    
    buffer.put("test data".getBytes());
    buffer.flip();
    
    Future<Integer> operation = fileChannel.write(buffer, position);
    buffer.clear();
    
    while(!operation.isDone());
    
    System.out.println("Write done");

    写入数据要注意file必须存在,否则会抛出NoSuchFileException。你可以这样创建文件

    if(!Files.exists(path)){
        Files.createFile(path);
    }

    通过CompletionHandler

    Path path = Paths.get("data/test-write.txt");
    if(!Files.exists(path)){
        Files.createFile(path);
    }
    AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);
    
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    long position = 0;
    
    buffer.put("test data".getBytes());
    buffer.flip();
    
    fileChannel.write(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() {
    
        @Override
        public void completed(Integer result, ByteBuffer attachment) {
            System.out.println("bytes written: " + result);
        }
    
        @Override
        public void failed(Throwable exc, ByteBuffer attachment) {
            System.out.println("Write failed");
            exc.printStackTrace();
        }
    });

    和read类似,write正常结束会回调completed,失败回调failed。

  • 相关阅读:
    DevOps与:cloud,IaC,Container,Microservices, Serverless
    2020年devops的7个发展趋势
    bash极简教程
    Jenkins pipeline jenkinsfile的两种写作方式声明式和脚本式
    Jenkins pipeline之声明式的jenkinsfile
    Linux基本开发环境配置git,c++,nodejs,nginx
    Linux centos8 VPS基本配置之SSH
    DevOps常用工具网址
    DevOps技能自查表
    DevOps的工作岗位的要求
  • 原文地址:https://www.cnblogs.com/lay2017/p/12916545.html
Copyright © 2011-2022 走看看