【问题标题】:Why output is incomplete using OutputStreamWriter with GZIPOutputStream?为什么使用带有 GZIPOutputStream 的 OutputStreamWriter 输出不完整?
【发布时间】:2014-06-25 09:58:37
【问题描述】:

我希望有人能阐明我在使用下面的代码时遇到的问题。

private static String encode(String data) throws IOException {
        try (
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            InputStream is = new ByteArrayInputStream(data.getBytes());
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            OutputStreamWriter writer = new OutputStreamWriter(new GZIPOutputStream(out));
            ) {
            char[] charBuffer = new char[data.length()];
            while (br.read(charBuffer) != -1) {
                writer.write(charBuffer);
            }
//          writer.close();
            return new String(Base64.encodeBase64(out.toByteArray()));
        }
    }

我的测试值是

This is some text that I can test some base64 encoding with.
I am getting a strange problem with the encoded value

当 writer.close 被注释掉时,我的输出是

H4sIAAAAAAAAAA==

当它没有被评论时,我的输出是

H4sIAAAAAAAAACWMzQ2DMBSD70jdwRP0VLED9y7wACuJRJKKZ37GJxTJF/uz/Y3J0eQ1E+IpKJowYLLSvOshozn7D1imOqcScCTF96sbYBmB0p0ZXKuVQPzWOi7M/1b747PjjN2WjRd08DfZcwAAAA==

第二个输出是正确的值,可以解码回原始值。 据我了解,流程如下:

  1. 尝试代码被执行
  2. 返回值被评估和存储
  3. 资源全部关闭
  4. 返回值。

那么为什么需要关闭编写器才能使输出正确?

【问题讨论】:

  • 尝试添加 writer.flush() 而不是关闭。可能是在您读取之前,该流尚未完全写入。
  • @AndrewVitkus 对不起,我应该提到我也尝试过冲洗。不幸的是,刷新而不是关闭仍然会导致编码不正确。
  • 我会用flush()重试。另外,正确地说,您的代码应该只写入 br.read() 实际读取的字符数,而不是 wole char 数组。
  • 由于关闭 writer 也应该关闭,您可以在 try 之外声明并在其中分配。然后,您也可以将 return 移到 try 之外。当然,这需要对 out 和其他此类不愉快的情况进行空检查,因此仅包括 close 可能是最优雅的解决方案。
  • 对不起,我之前的评论有误。必须关闭 GZIP 流才能完成压缩并写入结果。因此,刷新作者,并至少关闭 gzip 流。无论如何关闭作者都不会受到伤害。

标签: java outputstream gzipoutputstream


【解决方案1】:

这是因为当我们关闭编写器时,它会刷新流。当您不关闭写入器时,它不会被刷新(缓冲区只有在它变满或关闭时才会自动刷新)。所以你可以通过写作明确地做到这一点

writer.flush()

【讨论】:

    【解决方案2】:

    必须告知 GZIP 输出流何时完成压缩并将结果写入底层流。 close() 隐式刷新写入器并在 GZIP 流上调用 finish()

    因此,至少在编写器上调用 flush() 和 GZIP 流的 finish()close(),或者关闭编写器,这将完成所有这些并且无论如何都不会受到伤害。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多