在Java网络输入流中,为什么不建议这样做:
PdfReader localPdfReader = new PdfReader(item.getinputStream());
其中item是从客户端上传的FileItem
。
相反,建议这样做:
ByteArrayOutputStream output = new ByteArrayOutputStream();
IOUtils.copy(item.getInputStream(), output);
两者之间有什么不同?
的修改
我开始知道这是因为输入流是一个网络流。因此,一旦读取了一个字节,就无法再读取它了。所以你必须在使用之前将它复制到内存(IOUtils)。我的问题是在复制到内存时你还必须逐字节地读取流吗?那么为什么输入流不会在那里关闭?
答案 0 :(得分:1)
java中的流使用decorator pattern。它用于通过包装它们(装饰)向流添加功能。我最喜欢的是在GZipStream
周围使用FileStream
,以增加压缩效果。
答案 1 :(得分:1)
我猜不同之处在于 Reader和Inputstream 。在您的示例中,PDF文档是二进制数据,不应逐字符地传输,而是逐字节传输。有关Reader和InputStream的更多信息,请查看同一论坛中的this link。尽管它提到了通过Reader包装Stream,如前面提到的二进制数据,但是不鼓励这样做。
编辑:1
让我们检查Reader和InputStream的read方法是否正常工作
Reader.read()
returns整数,范围为0到65535(单个16位Unicode字符)
InputStream.read()
returns字节(8位带符号的二进制补码整数)数据
现在想象一下,如果你使用Reader来读取二进制数据(这是8位整数的序列),你将最终读取两个字节(8 * 2),而不是假设它是一个字符。
我还没有看到PdfReader
的代码,所以不确定它是否使用java.io.Reader
。这种解释纯粹是java.io.Reader/InputStream
。如果您分享一些链接或帖子,如果以您提到的方式使用PdfReader
,那么我将不胜感激。
编辑:2
记住:
如果您使用
PdfReader localPdfReader = new PdfReader(item.getinputStream());
然后PdfReader在内部从流中读取字节并使用它来验证。它不存储它以供进一步使用。
如果您使用
IOUtils
它将字节从网络复制到一个字节数组,以后可以在PdfReader
中使用,也可以在JDBC调用中将其存储在数据库中。
答案 2 :(得分:1)
相反,建议
由谁推荐?为什么?自1997年以来,我从未在任何Oracle或Sun文档中看到过这样的声明。来自其他来源的OTOH有很多错误信息。
在某些情况下可能会推荐 ,即您必须多次读取数据。这些情况非常罕见。