java - 找出流中有多少字节的更好方法?

标签 java apache stream streaming

目前,我依靠 ObjectInputStream.available() 方法来告诉我流中还剩下多少字节。原因 - 我正在对处理流的某些函数编写一些单元/集成测试,我只是想确保完成后 available() 方法返回 0。

不幸的是,在测试失败时(即,我已经向流发送了大约 8 个字节),我对 available() == 0 的断言在它应该为 false 时变成了 true。它应该显示 >0 或 8 字节!

我知道 available() 方法通常是不可靠的,但我认为它至少会显示 > 0 的内容!

是否有更可靠的方法来检查流是否为空(毕竟这是我的主要目标)?也许在 Apache IO 域或其他一些库中?

有人知道为什么 available() 方法如此极其不可靠吗?这有什么意义呢?或者,有具体的、正确的使用方法吗?


更新:

因此,正如你们中的许多人可以从评论中读到的那样,我面临的主要问题是在流的一端,我发送了一定数量的字节,但在另一端,并非所有字节都到达!

具体来说,我在一端发送 205498 字节,而在另一端仅收到 204988 字节,始终如一。我正在套接字中的线程之间控制此操作的两侧,但应该没关系。

这是我编写的用于收集所有字节的代码。

  public static int copyStream(InputStream readFrom, OutputStream writeTo, int bytesToRead)
      throws IOException {

    int bytesReadTotal = 0, bytesRead = 0, countTries = 0, available = 0, bufferSize = 1024 * 4;

    byte[] buffer = new byte[bufferSize];

    while (bytesReadTotal < bytesToRead) {

      if (bytesToRead - bytesReadTotal < bufferSize)
        buffer = new byte[bytesToRead - bytesReadTotal];

      if (0 < (available = readFrom.available())) {
        bytesReadTotal += (bytesRead = readFrom.read(buffer));
        writeTo.write(buffer, 0, bytesRead);
        countTries = 0;

      } else if (countTries < 1000)
        try {
          countTries++;
          Thread.sleep(1L);

        } catch (InterruptedException ignore) {}
      else

        break;
    }

    return bytesReadTotal;
  }

我将 countTries 变量放在那里只是为了看看会发生什么。即使其中没​​有 countTires,它也会在到达 BytesToRead 之前永远阻塞。

什么会导致流突然无限期地阻塞?我知道在另一端它完全发送了字节(因为它实际上使用了相同的方法,并且我看到它完成了该功能最后有完整的 BytesToRead 匹配 bytesReadTotal。但接收器没有。事实上,当我查看数组时,它们直到最后也完美匹配。

更新2

我注意到,当我在 copyStream 方法末尾添加 writeTo.flush() 时,它似乎又可以工作了。嗯..为什么同花在这种情况下如此重要。即,为什么使用它不会导致流永久阻塞?

最佳答案

available() 方法仅返回无阻塞可以读取的字节数(可能为 0)。为了查看流中是否还有字节,您必须使用 read()read(byte[]) 来返回读取的字节数。如果返回值为-1,则已到达文件末尾。

这个小代码片段将循环遍历一个InputStream,直到到达末尾(read() 返回-1)。我认为它永远不会返回 0,因为它应该阻塞,直到它可以读取 1 个字节或发现没有任何内容可供读取(因此返回 -1)

int currentBytesRead=0;
int totalBytesRead=0;
byte[] buf = new byte[1024];

while((currentBytesRead =in.read(buf))>0){
        totalBytesRead+=currentBytesRead;

}

关于java - 找出流中有多少字节的更好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18451664/

相关文章:

java - 如何使用java创建vcf文件?

java - Collections.binarySearch 是如何工作的?

java - 如何从Java中的单个长字符串中提取IP地址

apache - .htaccess 仅在存在时重定向到其他文件?

c# - 写在ASP.NET响应流上的一些问题

php - 如何逐行流式传输 GET 请求?

java - 如何从 firebase 检索 itemName 并将其用于 searchView?

apache - htaccess 不会重写子域

linux - 从源代码编译 LAMP - apache2 错误 "no MPM package installed"

node.js - Promise 解析为子流 stdout 并拒绝子流 stderr