更好地理解Java I / O.

时间:2012-05-09 06:29:28

标签: java apache-commons java-io

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

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

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

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

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

3 个答案:

答案 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

记住:

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

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

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

    如果您使用

    IOUtils
    

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

答案 2 :(得分:1)

  

相反,建议

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

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