如何正确扩展Java FilterOutputStream类? [英] How to properly extend Java FilterOutputStream class?

查看:307
本文介绍了如何正确扩展Java FilterOutputStream类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想大致监视文件上传的进度.我知道我可以重写MultipartEntity并使writeTo(OutputStream out)方法写入我创建的用于包装默认InputStream的FilterOutputStream类.有关如何执行此操作的完整详细信息,请在此处.

I would like to roughly monitor the progress of a file upload. I know that I can override the MultipartEntity and make the writeTo(OutputStream out) method write to a FilterOutputStream class that I created to wrap the default InputStream. For full details on how I did that, see my answer here.

但是,在仔细检查后,每个字节都会发送两次!我去了文档,看看发生了什么.看起来就像FilterOutputStream的 write(byte [],int,int)方法仅在循环中调用FilterOutputStream的write(byte)方法.它建议子类提供更有效的方法.我假设这涉及到调用基础OutputStream的write(byte [],int,int),并希望基础OutputStream有一种更好的将字节推入流的方法(doc的OutputStream的推荐子类覆盖了该方法,可以做得更好)而不是简单地循环遍历OutputStream#write(byte)方法).

However, upon closer inspection this counts every byte sent twice! I went to the documentation to see what was up. Looks like FilterOutputStream's write(byte[], int, int) method simply calls the FilterOutputStream's write(byte) method in a loop. It recommends subclasses to provide a more efficient method. I would assume this to involve calling the underlying OutputStream's write(byte[], int, int) and hoping that the underlying OutputStream has a better method of pushing bytes onto the stream (doc's recommend subclasses of OutputStream override this method and do a better job than simply looping over the OutputStream#write(byte) method).

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

This is where I find myself in a predicament. I can't guarantee that the MultipartEntity#writeTo(OutputStream) will always result in a call to OutputStream.write(byte[],int,int), so if I count the bytes sent there then I might miss some that are sent using the write(byte) method. However, I can't count in the write(byte) method, because the OutputStream.write(byte[],int,int) method may never call the write(byte) method.

一个答案是在子类的write(byte [],int,int)方法内调用super.write(byte [],int,int).然后,我知道这将简单地遍历write(byte)方法,一次写入一个字节.然后,我可以计算写在write(byte)方法内部的所有字节.但是,这效率低下,因此文档直接建议不要这样做.我确信OutputStream的某些子类可以一次将多个字节写入流,所以不使用这种优势是很愚蠢的.

One answer is to call super.write(byte[],int,int) inside of my subclass's write(byte[],int,int) method. Then, I know that this will simply loop over the write(byte) method, writing one byte at a time. I can then count all bytes written inside of the write(byte) method. However, this is inefficient, and the docs directly recommend against it. I am sure that some of the subclasses of OutputStream manage to write multiple bytes to the stream at once, so it's silly not to use that advantage.

那么,如何正确重写FilterOutputStream以提高效率并计算发送的所有字节数?

So, how do I properly override FilterOutputStream to be both efficient and count all bytes sent?

很抱歉,如果时间太长,我已将其设为Wiki,以防有人能比我更好地描述问题.

Sorry if this is long, I have made it a wiki in case anyone can describe the issue better than I.

推荐答案

在计数流上调用同一方法时,只需在基础流上调用write(byte[] b, int off, int len).这将永远不会导致计数流上的write(byte b)方法被调用.

Just call write(byte[] b, int off, int len) on the underlying stream when the same method is called on your counting stream. That will never cause the write(byte b) method on the counting stream to be called.

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

Also, your CountingOutputStream in the linked answer has a number of other issues.

  1. 即使FilterOutputStream为您将包装的输出流存储在名为out的受保护字段中,它也有自己的引用.
  2. 在调用write(byte[] b, int off, int len)时,它会将len个字节写入包装的流中,但只会将传输的字节数加1.
  3. 它不会增加write(byte b)中传输的字节.
  1. It has its own reference to the wrapped output stream even though FilterOutputStream stores that for you in a protected field called out.
  2. It writes len bytes to the wrapped stream when write(byte[] b, int off, int len) is called, but only adds 1 to the number of bytes transferred.
  3. It doesn't increment the bytes transferred in write(byte b).

这篇关于如何正确扩展Java FilterOutputStream类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆