【问题标题】:Read all bytes from InputStream in non blocking mode以非阻塞模式从 InputStream 中读取所有字节
【发布时间】:2019-06-07 07:12:25
【问题描述】:

试图找到在非阻塞模式下从InputStream 读取所有字节的解决方案。当没有可用数据时,函数下方的 inputStream.read() 部分将永远阻塞。

private static String extract(InputStream inputStream) throws IOException { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream();               
    byte[] buffer = new byte[1024];
    int read = 0;
    while ((read = inputStream.read(buffer, 0, buffer.length)) != -1) {
        baos.write(buffer, 0, read);
    }       
    baos.flush();       
    return  new String(baos.toByteArray(), "UTF-8");
}

如何在不阻塞的情况下读取所有字节?

【问题讨论】:

  • 你试过 IOUtils.toString(inputstream) 吗?
  • 它;在非阻塞模式下无法从InputStream 读取。您必须使用面向缓冲区的 IO,而不是面向流的 IO。查看 NIO 包
  • 您无法读取 任何 个字节而不会有阻塞的风险。你的问题体现了一个矛盾的术语。 InputStream 正在阻塞,期间。但是,如果您想“读取所有字节”,为什么您认为需要非阻塞模式?

标签: java inputstream


【解决方案1】:

我假设您希望阅读超时。

对于 URLConnection(如果 InputStream 源于此),您可以设置其他超时,并检查最佳块大小(来自发送者)。

对于 Socket,存在相同的功能。

可以使用线程使自己超时:this I found on SO

Future 似乎也很合适:

ExecutorService service = Executors.newFixedThreadPool(2); // Or whatever.
// Callable<String> callable = () -> extract(inputStream);
Future<String> future = service.submit(() -> extract(inputStream));
try {
    String s = future.get(3, TimeUnit.SECONDS);
} catch (Exception e){
    e.printStackTrace();
    future.cancel(true);
    inputStream.close();
}

【讨论】:

  • 他想读取所有字节,为什么需要超时?或者确实是非阻塞模式?
  • @user207421 “当没有可用数据时永远阻塞” - 看起来他想阻止这种情况。我提出的解决方案:合理的操作超时。是的,那么你根本就没有数据。顺便说一句,因为这是一个未来,您可以尽早提交任务,并且在获取的那一刻甚至可能有一个 0 响应时间。
【解决方案2】:

您可以使用InputStream.available() 方法来测试在读取之前有多少字节可用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    • 2013-01-05
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多