【问题标题】:BufferedInputStream mark/reset issueBufferedInputStream 标记/重置问题
【发布时间】:2016-02-18 03:13:49
【问题描述】:

有人可以帮我弄清楚我在这里做错了什么吗?这个方法除了在调用 new InputStreamReader(stream, getSet(stream); 时产生空行之外什么都不做

谢谢大家!

private static final byte[] UTF8_BOM = new byte[] {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};

private static final byte[] UTF16LE_BOM = new byte[] {(byte) 0xFF, (byte) 0xFE};

private static final byte[] UTF16BE_BOM = new byte[] {(byte) 0xFE, (byte) 0xFF};

public static Charset getSet(final InputStream stream) throws IOException {

        final byte[] UTF8_Buffer = new byte[3];
        final byte[] UTF16LE_Buffer = new byte[2];
        final byte[] UTF16BE_Buffer = new byte[2];
        int byteValue;
        InputStream bufferedStream = new BufferedInputStream(stream);
        bufferedStream.mark(3);

        byteValue = stream.read();

        UTF16LE_Buffer[0] = (byte) byteValue;
        UTF16BE_Buffer[0] = (byte) byteValue;
        UTF8_Buffer[0] = (byte) byteValue;

        byteValue = bufferedStream.read();
        UTF16LE_Buffer[1] = (byte) byteValue;
        UTF16BE_Buffer[1] = (byte) byteValue;
        UTF8_Buffer[1] = (byte) byteValue;
        if (Arrays.equals(UTF16LE_Buffer, UTF16LE_BOM)) {
          return StandardCharsets.UTF_16LE;
        } else if (Arrays.equals(UTF16BE_Buffer, UTF16LE_BOM)) {
          return StandardCharsets.UTF_16BE;
        } else {
          byteValue = bufferedStream.read();
          UTF8_Buffer[2] = (byte) byteValue;
          if (Arrays.equals(UTF8_Buffer, UTF8_BOM)) {
            return StandardCharsets.UTF_8;
          }
        }

        bufferedStream.reset();
        return StandardCharsets.UTF_8;
      }

【问题讨论】:

  • 你试过在调试模式下运行代码吗?
  • 是的,我似乎在第一次bufferedStream.read() 通话中得到-1。感谢阿尔伯特!为了格式化我的代码,我无法将所有内容都放入代码块中
  • 我刚刚在调试中再次运行它,我错了,我得到的值不是-1。
  • 你能不能把值写在这里以便其他人也能看到
  • 没错,第一次调用返回:224 第二次返回164,第三次调用返回174

标签: java java-io bufferedinputstream


【解决方案1】:

我找到了解决问题的方法。

我从这里改变了方法:

public static String readText(@Nonnull final InputStream stream) throws IOException {
     try (final Reader reader = new InputStreamReader(stream, getCharset(stream))) {....

到这里:

public static String readText(@Nonnull final InputStream stream) throws   IOException {
    final BufferedInputStream bufferedStream = new BufferedInputStream(stream);
    try (final Reader reader = new InputStreamReader(bufferedStream, getCharset(bufferedStream))) {...

感谢所有帮助的人!

【讨论】:

  • 您没有“找到”问题的解决方案。我提供了。您应该接受和/或投票赞成您认为有用的任何答案。这个答案包含对您以前从未发布过的代码的更改。没用,而且有点烦人。
【解决方案2】:

这里的问题是您已经使用BufferedInputStream 从输入流中读取了两个或三个字节。在BufferedInputStream 上调用mark()/reset() 允许您从BufferedInputStream 重新读取这些字节, 但它对底层流没有任何作用。

您应该更改此方法的调用者以传递BufferedInputStream 而不是InputStream,并从方法内部删除new BufferedInputStream,以便调用者和被调用者都标记/重置同一流.如果调用者没有传递支持mark()/reset() 的InputStream,则调用其中任何一个都会引发异常。

【讨论】:

  • 还有其他解决方案吗?在 InputStreams 的情况下,我应该对接口或抽象超类进行编程。另外它看起来不像 BufferedInputStream 支持文件路径作为输入?
  • 好吧,让我换一种说法,见编辑。你可以做new BufferedInputStream(new FileInputStream(...))。
  • 这适用于我的任务的一个方面,但它破坏了我使用 ByteArrayInputStream 调用该方法的所有单元测试。当我现有的单元测试在重构后失败时,我知道我走错了路。在大多数情况下。但是感谢您的提示,它确实按您所说的那样工作。
  • 为什么它会破坏你的单元测试? ByteArrayInputStream 支持标记/重置。
  • 因为我将方法签名从 readText(InputStream) 更改为 readText(BufferedInputStream) 所以我不能再调用 readText(ByteArrayInputStream)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-08
  • 1970-01-01
  • 2011-02-19
  • 2012-03-28
  • 2020-04-28
  • 2023-03-08
相关资源
最近更新 更多