java - 更好地理解 Java I/O

标签 java apache-commons java-io

在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

记住:

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

如果您使用

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

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

如果您使用

IOUtils

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

关于java - 更好地理解 Java I/O,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10510847/

相关文章:

java - 依赖注入(inject)是如何手动实现的?

java - 在同一行中定义 shell 变量会传递给 (java) 进程,但不会在不同的行中

java - 使用 Apache Commons VFS 通过 FTP URI 导航到根目录

java - SequenceInputStream 中每个新流的新行

java - 如何在Android的onCreateView中调用方法

java - 当方法返回类型为 void 时,SpringBoot Controller 中的 CompletableFuture 不起作用

java - 超过 FileSizeMax 时取消文件上传

java - Java 中的 IMAP 客户端 : JavaMail API or Apache Commons Net?

java - Spring - 将文件内容从类路径注入(inject)到带注释的成员中

java - 为什么 java.net.SocketInputStream 不存在?