2

在 Java 网络输入流中,为什么不建议这样做:

 PdfReader localPdfReader = new PdfReader(item.getinputStream());

其中 item 是FileItem从客户端上传的。相反,建议这样做:

ByteArrayOutputStream output = new ByteArrayOutputStream();
IOUtils.copy(item.getInputStream(), output);

两者有什么区别?
编辑
我才知道这是因为这里的输入流是网络流。因此,一旦读取了一个字节,您就无法再读取它。所以你必须在使用它之前将它复制到内存(IOUtils)。我的问题是,在复制到内存时,您还必须逐字节读取流,对吗?那么为什么输入流不在那里关闭呢?

4

3 回答 3

1

java中的流使用装饰器模式。它用于通过包装(装饰)向流添加功能。我最喜欢的是使用GZipStream,FileStream来增加压缩。

于 2012-05-09T06:34:53.157 回答
1

我想区别在于Reader 和 Inputstream。在您的示例中,PDF 文档是二进制数据,不应逐字符传输,而应逐字节传输。查看同一论坛中的此链接,了解有关 Reader 和 InputStream 的更多信息。尽管它提到了 Reader 对 Stream 的包装,但正如前面提到的二进制数据,这应该是不鼓励的。

编辑:1

让我们检查一下 Reader 和 InputStream 的 read 方法的工作方式

Reader.read() 返回0 到 65535 范围内的整数(单个 16 位 Unicode 字符)

InputStream.read() 返回数据的字节(8 位有符号二进制补码整数)

现在想象一下,如果您使用 Reader 读取二进制数据(即 8 位整数序列),您最终将读取两个字节 (8*2) 而不是假设它是一个字符。

我还没有看到代码, PdfReader所以不确定它是否使用java.io.Reader. 这种解释纯粹是为了java.io.Reader/InputStream。如果您分享一些链接或帖子,其中说明PdfReader如果以您提到的方式使用,我将不胜感激。

编辑:2

记住:

  1. 从网络中,您只能读取一次流字节。
  2. 如果您需要这些字节用于多个任务,最好将这些字节存储在数组中并多次使用同一个数组

如果你使用

PdfReader localPdfReader = new PdfReader(item.getinputStream());

然后 PdfReader 在内部从流中读取字节并使用它进行验证。它不会存储它以供进一步使用。

如果你使用

IOUtils

它将字节从网络复制到一个字节数组,稍后可以使用该数组PdfReader以及 JDBC 调用将其存储在 DB 中。

于 2012-05-09T06:35:54.907 回答
1

相反,这是推荐的

由谁推荐?为什么?自 1997 年以来,我从未在任何 Oracle 或 Sun 文档中看到过这样的声明。OTOH 有很多来自其他来源的错误信息。

在某些情况下可能会推荐它,即您必须多次读取数据的情况。这些情况非常罕见。

于 2012-05-12T00:20:52.367 回答