Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何正确扩展Java FilterOutputStream类?_Java_Overriding_Subclass_Subclassing_Outputstream - Fatal编程技术网

如何正确扩展Java FilterOutputStream类?

如何正确扩展Java FilterOutputStream类?,java,overriding,subclass,subclassing,outputstream,Java,Overriding,Subclass,Subclassing,Outputstream,我想大致监控文件上传的进度。我知道我可以重写MultipartEntity并使writeTo(OutputStream out)方法写入我创建的用于包装默认InputStream的FilterOutputStream类。有关我是如何做到这一点的详细信息,请参阅我的答案 然而,仔细检查后,这会计算发送的每个字节两次!我看了一下文档,看看发生了什么事。看起来FilterOutputStream的方法只是在循环中调用FilterOutputStream的write(byte)方法。它建议子类提供更有效

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

然而,仔细检查后,这会计算发送的每个字节两次!我看了一下文档,看看发生了什么事。看起来FilterOutputStream的方法只是在循环中调用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,以防任何人都能比我更好地描述这个问题。

只要调用
write(byte[]b,int off,int len)
就可以在基础流上编写(byte[]b,int-off,int-len)。这永远不会导致调用计数流上的
write(byte b)
方法

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

  • 即使
    FilterOutputStream
    将其存储在名为
    out
    的受保护字段中,它也有自己对包装输出流的引用
  • 调用
    write(byte[]b,int off,int len)
    时,它会将
    len
    字节写入包装的流,但只会将传输的字节数增加1
  • 它不会增加
    写入(字节b)
    中传输的字节数
  • 当在计数流上调用相同的方法时,只需在底层流上调用
    write(byte[]b,int off,int len)
    。这永远不会导致调用计数流上的
    write(byte b)
    方法

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

  • 即使
    FilterOutputStream
    将其存储在名为
    out
    的受保护字段中,它也有自己对包装输出流的引用
  • 调用
    write(byte[]b,int off,int len)
    时,它会将
    len
    字节写入包装的流,但只会将传输的字节数增加1
  • 它不会增加
    写入(字节b)
    中传输的字节数