0

我想大致监控文件上传的进度。我知道我可以覆盖 MultipartEntity 并使 writeTo(OutputStream out) 方法写入我为包装默认 InputStream 而创建的 FilterOutputStream 类。有关我如何做到这一点的完整详细信息,请参阅我的答案here

然而,经过仔细检查,这会将每个字节发送两次!我去文档看看发生了什么。看起来 FilterOutputStream 的write(byte[], int, int)方法只是在循环中调用 FilterOutputStream 的 write(byte) 方法。它推荐子类以提供更有效的方法。我假设这涉及调用底层 OutputStream 的 write(byte[], int, int) 并希望底层 OutputStream 有更好的将字节推送到流上的方法(文档推荐的 OutputStream 子类覆盖此方法并做得更​​好而不是简单地循环 OutputStream#write(byte) 方法)。

这就是我发现自己陷入困境的地方。我不能保证 MultipartEntity#writeTo(OutputStream) 总是会导致调用 OutputStream.write(byte[],int,int),所以如果我计算那里发送的字节数,那么我可能会错过一些使用发送的字节数写(字节)方法。但是,我不能算入 write(byte) 方法,因为 OutputStream.write(byte[],int,int) 方法可能永远不会调用 write(byte) 方法。

一个答案是在我的子类的 write(byte[],int,int) 方法中调用 super.write(byte[],int,int) 。然后,我知道这将简单地循环 write(byte) 方法,一次写入一个字节。然后我可以计算在 write(byte) 方法中写入的所有字节。但是,这是低效的,文档直接建议不要这样做。我确信 OutputStream 的一些子类设法一次将多个字节写入流,所以不利用这个优势是愚蠢的。

那么,如何正确覆盖 FilterOutputStream 以既高效又计算所有发送的字节数?

对不起,如果这很长,我已经把它变成了一个维基,以防有人能比我更好地描述这个问题。

4

1 回答 1

3

当在计数流上调用相同的方法时,只需调用write(byte[] b, int off, int len)底层流。这永远不会导致write(byte b)计数流上的方法被调用。

此外,您CountingOutputStream在链接的答案中还有许多其他问题。

  1. 它对包装的输出流有自己的引用,即使FilterOutputStream它为您存储在一个名为out.
  2. 它在被调用len时将字节写入包装的流write(byte[] b, int off, int len),但仅将传输的字节数加 1。
  3. 它不会增加传输的字节数write(byte b)
于 2010-07-02T04:29:29.080 回答