如何正确扩展Java FilterOutputStream类?

时间:2010-07-02 03:48:05

标签: java override subclass subclassing outputstream

我想粗略监控文件上传的进度。我知道我可以覆盖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,以防有人能比我更好地描述这个问题。

1 个答案:

答案 0 :(得分: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)中传输的字节数。