举报投诉联系我们 手机版 热门标签 VUE中文网
您的位置:VUE中文网 > java异步io Java 异步I/O

java异步io Java 异步I/O

2023-06-15 05:17 Java教程

java异步io Java 异步I/O

java异步io

Java异步IO是一种非阻塞的I/O模型,它可以让程序在不阻塞当前线程的情况下进行I/O操作。它使用一个单独的线程来处理I/O操作,而不是在当前线程中处理,从而减少了I/O操作对当前线程的影响。

Java异步IO有助于提高应用性能,因为它可以让应用在不阻塞当前线程的情况下进行I/O操作。它可以让应用在不同的I/O操作之间切换,而不会因为一个I/O操作耗时过久而导致其他I/O操作无法执行。

public class AsyncIOExample {

    public static void main(String[] args) {

        // 创建一个异步IO对象
        AsynchronousFileChannel fileChannel = 
            AsynchronousFileChannel.open(Paths.get("test.txt"));

        // 创建一个ByteBuffer对象,用于存储文件内容
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        // 使用异步IO读取文件内容到ByteBuffer中
        fileChannel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {

            @Override
            public void completed(Integer result, ByteBuffer attachment) {

                System.out.println("Bytes read: " + result);

                // 输出读取到的文件内容
                attachment.flip();  // 将buffer从写入改成读取  
                while (attachment.hasRemaining()) {  
                    System.out.print((char) attachment.get());  
                }  

            }

            @Override  // 处理读取失败时的回调方法  
            public void failed(Throwable exc, ByteBuffer attachment) {  

                System.out.println("Read failed");  

            }  

        }); 

    } 
} 															    

Java 异步I/O

Java IO教程 - Java异步I/O


在同步文件I/O中,对I/O操作的请求将等待,直到I/O操作完成。

在异步文件I/O中,I/O操作的请求由系统异步执行。

当系统完成文件I/O时,它通知应用程序其请求的完成。

java.nio.channels.AsynchronousFileChannel类表示异步文件通道。

AsynchronousFileChannel类的静态open()方法获取AsynchronousFileChannel类的实例。

以下代码显示了如何获取WRITE的异步文件通道。

Path  path   = Paths.get("C:Java_Devrainbow.txt");
AsynchronousFileChannel afc   = AsynchronousFileChannel.open(path, WRITE,  CREATE);

AsynchronousFileChannel提供了两种方法来处理异步文件I/O操作的结果。

  • Using a java.util.concurrent.Future object.
  • Using a java.nio.channels.CompletionHandler object.

支持异步文件I/O操作的AsynchronousFileChannel类的每个方法有两个版本。

一个版本返回一个Future对象,我们可以使用它来处理所请求的异步操作的结果。

Future对象的get()方法返回写入文件通道的字节数。

以下代码使用返回Future对象的write()方法的版本:

ByteBuffer dataBuffer  = a buffer;
long  startPosition = 0;
Future<Integer> result = afc.write(dataBuffer, startPosition);

一旦我们得到一个Future对象,我们可以使用轮询方法或阻塞等待方法来处理异步文件I/O的结果。

下面的代码显示了轮询方法,它将继续调用Future对象的isDone()方法,以检查I/O操作是否完成:

while (!result.isDone()) {
}
int writtenNumberOfBytes = result.get();

AsynchronousFileChannel类的另一个版本的方法获得一个CompletionHandler对象,当请求的异步I/O操作完成或失败时,该对象的方法被调用。

CompletionHandler接口有两个方法:completed()和failed()。

当所请求的I/O操作成功完成时,将调用completed()方法。

当请求的I/O操作时失败,则调用failed()方法。

以下代码使用Attachment类的对象作为完成处理程序的附件:

class  Attachment {
    public Path  path;
    public  ByteBuffer buffer;
    public  AsynchronousFileChannel asyncChannel;
}
class MyHandler implements CompletionHandler<Integer,  Attachment>   {
    @Override
    public void  completed(Integer result, Attachment attach)  {
        // Handle  completion of  the   I/O  operation
    }
    
    @Override
    public void  failed(Throwable e,  Attachment attach)  {
        // Handle  failure of  the   I/O  operation
    }
}

以下代码使用MyHandler实例作为异步写操作的完成处理程序。

MyHandler handler = new MyHandler();
ByteBuffer dataBuffer  = get   a  data buffer;
Attachment attach  = new Attachment(); 
attach.asyncChannel = afc; 
attach.buffer = dataBuffer; 
attach.path = path;

// Perform  the   asynchronous write operation 
afc.write(dataBuffer, 0, attach, handler);

以下代码演示了如何使用CompletionHandler对象来处理对文件的异步写入的结果。

import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.WRITE;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main {
  public static void main(String[] args) throws Exception {
    Path path = Paths.get("test.txt");
    AsynchronousFileChannel afc = AsynchronousFileChannel.open(path, WRITE,
        CREATE);
    WriteHandler handler = new WriteHandler();
    ByteBuffer dataBuffer = getDataBuffer();
    Attachment attach = new Attachment();
    attach.asyncChannel = afc;
    attach.buffer = dataBuffer;
    attach.path = path;

    afc.write(dataBuffer, 0, attach, handler);

    System.out.println("Sleeping for 5  seconds...");
    Thread.sleep(5000);
  }
  public static ByteBuffer getDataBuffer() {
    String lineSeparator = System.getProperty("line.separator");
    StringBuilder sb = new StringBuilder();
    sb.append("test");
    sb.append(lineSeparator);
    sb.append("test");
    sb.append(lineSeparator);
    String str = sb.toString();
    Charset cs = Charset.forName("UTF-8");
    ByteBuffer bb = ByteBuffer.wrap(str.getBytes(cs));
    return bb;
  }
}
class Attachment {
  public Path path;
  public ByteBuffer buffer;
  public AsynchronousFileChannel asyncChannel;
}

class WriteHandler implements CompletionHandler<Integer, Attachment> {
  @Override
  public void completed(Integer result, Attachment attach) {
    System.out.format("%s bytes written  to  %s%n", result,
        attach.path.toAbsolutePath());
    try {
       attach.asyncChannel.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override
  public void failed(Throwable e, Attachment attach) {
    try {
      attach.asyncChannel.close();
    } catch (IOException e1) {
      e1.printStackTrace();
    }
  }
}

例子

以下代码演示了如何使用Future对象来处理对文件的异步写入的结果。

import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.WRITE;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.Future;

public class Main {
  public static ByteBuffer getDataBuffer() {
    String lineSeparator = System.getProperty("line.separator");

    StringBuilder sb = new StringBuilder();
    sb.append("test");
    sb.append(lineSeparator);

    String str = sb.toString();
    Charset cs = Charset.forName("UTF-8");
    ByteBuffer bb = ByteBuffer.wrap(str.getBytes(cs));

    return bb;
  }

  public static void main(String[] args) throws Exception {
    Path path = Paths.get("test.txt");

    try (AsynchronousFileChannel afc = AsynchronousFileChannel.open(path,
        WRITE, CREATE)) {
      ByteBuffer dataBuffer = getDataBuffer();
      Future<Integer> result = afc.write(dataBuffer, 0);
      while (!result.isDone()) {
        System.out.println("Sleeping for 2  seconds...");
        Thread.sleep(2000);
      }
      int writtenBytes = result.get();
      System.out.format("%s bytes written  to  %s%n", writtenBytes,
          path.toAbsolutePath());

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

上面的代码生成以下结果。


例2

以下代码演示了如何使用CompletionHandler对象来处理从文件进行异步读取的结果。

import static java.nio.file.StandardOpenOption.READ;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main {
  public static void main(String[] args) throws Exception{
    Path path = Paths.get("test.txt");
    AsynchronousFileChannel afc = AsynchronousFileChannel.open(path, READ);
    ReadHandler handler = new ReadHandler();
    int fileSize = (int) afc.size();
    ByteBuffer dataBuffer = ByteBuffer.allocate(fileSize);

    Attachment attach = new Attachment();
    attach.asyncChannel = afc;
    attach.buffer = dataBuffer;
    attach.path = path;

    afc.read(dataBuffer, 0, attach, handler);

    System.out.println("Sleeping for 5  seconds...");
    Thread.sleep(5000);
  }
}
class Attachment {
  public Path path;
  public ByteBuffer buffer;
  public AsynchronousFileChannel asyncChannel;
}

class ReadHandler implements CompletionHandler<Integer, Attachment> {
  @Override
  public void completed(Integer result, Attachment attach) {
    System.out.format("%s bytes read   from  %s%n", result, attach.path);
    System.out.format("Read data is:%n");
    byte[] byteData = attach.buffer.array();
    Charset cs = Charset.forName("UTF-8");
    String data = new String(byteData, cs);
    System.out.println(data);
    try {
      // Close the channel
      attach.asyncChannel.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override
  public void failed(Throwable e, Attachment attach) {
    System.out.format("Read operation  on  %s  file failed."
        + "The  error is: %s%n", attach.path, e.getMessage());
    try {
      // Close the channel
      attach.asyncChannel.close();
    } catch (IOException e1) {
      e1.printStackTrace();
    }
  }
}

上面的代码生成以下结果。

例3

以下代码显示了如何使用Future对象来处理从文件进行异步读取的结果。它使用等待方法(Future.get()方法调用)等待异步文件I/O完成。

import static java.nio.file.StandardOpenOption.READ;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

public class Main {
  public static void main(String[] args) throws Exception {
    Path path = Paths.get("test.txt");

    try (AsynchronousFileChannel afc = AsynchronousFileChannel.open(path, READ)) {
      int fileSize = (int) afc.size();
      ByteBuffer dataBuffer = ByteBuffer.allocate(fileSize);

      Future<Integer> result = afc.read(dataBuffer, 0);
      int readBytes = result.get();

      System.out.format("%s bytes read   from  %s%n", readBytes, path);
      System.out.format("Read data is:%n");

      byte[] byteData = dataBuffer.array();
      Charset cs = Charset.forName("UTF-8");
      String data = new String(byteData, cs);

      System.out.println(data);
    } catch (IOException ex) {
      ex.printStackTrace();
    }
  }
}

上面的代码生成以下结果。

阅读全文
以上是VUE中文网为你收集整理的java异步io Java 异步I/O全部内容。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。
相关文章
© 2024 VUE中文网 vue88.com 版权所有 联系我们