在Java网络输入流中,为什么不建议这样做:
PdfReader localPdfReader = new PdfReader(item.getinputStream());
其中 item 是从客户端上传的 FileItem
。
相反,建议这样做:
ByteArrayOutputStream output = new ByteArrayOutputStream();
IOUtils.copy(item.getInputStream(), output);
两者有什么区别?
编辑
我才知道这是因为这里的inputstream是一个网络流。因此,一旦读取了一个字节,就无法再读取它。所以在使用之前必须将其复制到内存(IOUtils)。我的问题是,在复制到内存时,您还必须逐字节读取流,对吧?那么为什么输入流没有在那里关闭呢?
最佳答案
我猜差异在于Reader 和Inputstream。在您的示例中,PDF 文档是二进制数据,不应逐字符传输,而应逐字节传输。检查this link在同一论坛中了解有关 Reader 和 InputStream 的更多信息。尽管它提到了 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 调用以将其存储在数据库中。
关于java - 更好地理解 Java I/O,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10510847/