我想粗略监控文件上传的进度。我知道我可以覆盖MultipartEntity并使writeTo(OutputStream out)方法写入我创建的FilterOutputStream类来包装默认的InputStream。有关我如何做到这一点的详细信息,请参阅我的回答here。
然而,经过仔细检查,这会计算两次发送的每个字节!我去了文档,看看是什么。看起来FilterOutputStream的write(byte[], int, int)方法只是在循环中调用FilterOutputStream的write(byte)方法。它建议使用子类来提供更有效的方法。我假设这涉及调用底层的OutputStream的write(byte [],int,int)并希望底层的OutputStream有一个更好的方法将字节推送到流上(doc的推荐子类OutputStream覆盖这个方法并做得更好而不是简单地循环OutputStream#write(byte)方法)。
这是我发现自己陷入困境的地方。我不能保证MultipartEntity#writeTo(OutputStream)总是会调用OutputStream.write(byte [],int,int),所以如果我计算那里发送的字节,那么我可能会错过一些使用write(byte)方法。但是,我无法计算write(byte)方法,因为OutputStream.write(byte [],int,int)方法可能永远不会调用write(byte)方法。
一个答案是在我的子类的write(byte [],int,int)方法中调用super.write(byte [],int,int)。然后,我知道这将简单地遍历write(byte)方法,一次写入一个字节。然后我可以计算写(byte)方法内写的所有字节。但是,这是低效的,文档直接建议不要这样做。我确信OutputStream的某些子类能够同时将多个字节写入流中,因此不使用该优势是愚蠢的。
那么,如何正确覆盖FilterOutputStream以提高效率并计算发送的所有字节数?
对不起,如果这很长,我已经把它变成了wiki,以防有人能比我更好地描述这个问题。
答案 0 :(得分:3)
在计数流上调用相同的方法时,只需在基础流上调用write(byte[] b, int off, int len)
。这永远不会导致调用计数流上的write(byte b)
方法。
此外,链接答案中的CountingOutputStream
还有许多其他问题。
FilterOutputStream
将您存储在名为out
的受保护字段中。len
时,它会将write(byte[] b, int off, int len)
个字节写入包装的流,但只会将传输的字节数加1。write(byte b)
中传输的字节数。