How to properly extend Java FilterOutputStream class?

浪子不回头ぞ 提交于 2019-12-12 01:18:58

问题


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.

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).

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.

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.

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

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


回答1:


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.

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

  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).


来源:https://stackoverflow.com/questions/3163131/how-to-properly-extend-java-filteroutputstream-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!