Java:写入 ByteArrayOutputStream 时出现 IOException?

发布于 2024-11-14 01:41:14 字数 815 浏览 5 评论 0原文

由于 ByteArrayOutputStream 只是写入内存,因此永远不会发生 IOException 。但是,由于 OutputStream 接口的约定,所有流操作都在其 throws 子句中定义 IOException

“处理”这个永远不会发生的 IOException 的正确方法是什么?简单地将操作包装在空的 try-catch 块中?

或者是否存在 ByteArrayOutputStream 可能引发异常的实际情况?

(另请参阅:如何以安全且可读的方式处理我知道永远不会抛出的 IOException?

编辑

正如乔恩指出的那样, ByteArrayOutputStream 没有在它定义的 write 方法上声明 throws 子句 - 但是,它继承了 write(byte[]) 来自 OutputStream,并且确实会抛出 IOEXception (很奇怪的是 BAOS 不会重写此方法,因为它可以替换超类版本——一次写入一个字节——使用更高效的 arraycopy 调用)

Since ByteArrayOutputStream simply writes to memory, an IOException should never occur. However, because of the contract of the OutputStream interface, all stream operations define IOException in their throws clause.

What is the correct way to "handle" this never-occurring IOException? Simply wrap operations in an empty try-catch block?

Or are there any actual situations where ByteArrayOutputStream could throw an exception?

(See also: How can I handle an IOException which I know can never be thrown, in a safe and readable manner?)

EDIT

As Jon points out, ByteArrayOutputStream doesn't declare a throws clause on the write methods it defines -- however, it inherits write(byte[]) from OutputStream, and that one does throw IOEXception (quite odd that BAOS wouldn't override this method, as it could replace the superclass version -- which writes one byte at a time -- with a far more efficient arraycopy call)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

怪异←思 2024-11-21 01:41:15

嗯,ByteArrayOutputStream 不会声明它的任何方法都会抛出 IOException,除了 writeToclose< /代码>。 (老实说,我不知道为什么 close 仍然声明它。)

如果您有一个 OutputStream 类型的引用,您仍然会看到 throws 声明当然,从那以后。

我不会使用空的 catch 块 - 我会抛出类似 IllegalStateException 或类似的未经检查的异常:这意味着您处于确实的情况期待着,但有些事情出了严重的问题。

Well, ByteArrayOutputStream doesn't declare that any of its methods throw IOException except writeTo and close. (I don't know why close still declares it, to be honest.)

If you've got a reference of type OutputStream though, you would still see the throws declarations from that, of course.

I wouldn't use an empty catch block - I'd throw something like IllegalStateException or a similar unchecked exception: it means you're in a situation you really don't expect, and something's gone badly wrong.

遗忘曾经 2024-11-21 01:41:15

从Java 11开始,还有一个新方法 ByteArrayOutputStream.writeBytes (byte[]) 也不会抛出 IOException

/**
 * Writes the complete contents of the specified byte array
 * to this {@code ByteArrayOutputStream}.
 *
 * ...
 *
 * @since   11
 */
public void writeBytes(byte b[]) {
    write(b, 0, b.length);
}

如果您不想处理永远不会抛出的 IOException,则可以使用此方法抛出。

Since Java 11, there is also a new method ByteArrayOutputStream.writeBytes(byte[]) which does not throw an IOException as well:

/**
 * Writes the complete contents of the specified byte array
 * to this {@code ByteArrayOutputStream}.
 *
 * ...
 *
 * @since   11
 */
public void writeBytes(byte b[]) {
    write(b, 0, b.length);
}

You could use this method if you don't want to handle an IOException which is never thrown.

看透却不说透 2024-11-21 01:41:15

我刚刚注意到 ByteArrayOutputStream.write 实际上并没有声明 IOException ——但是每当我使用它时 Eclipse 都会抱怨未处理的异常......奇怪。

这很容易解释。您可能已经做过类似的事情:

    OutputStream os = new ByteArrayOutputStream();
    ...
    os.write();

“问题”是您将该方法调用为 OutputStream.write() 而不是 ByteArrayOutputStream.write()。所以编译器说:

“啊... OutputStream 上的 write() 可能会抛出 IOException,所以你必须处理它。”

它不能说:

“这个特定的 OutputStream 实际上是一个 ByteArrayOutputStream ...所以我们会让你放过。”

因为JLS不允许。

这是一种边缘情况,遵循“最佳实践”,通过对接口而不是实现类进行编码,会带来麻烦。

好吧...

  • 这是一个轻柔的咬合,而不是一个完整的咬合。
  • OutputStream 是作为 Java 类而不是 Java 接口实现的,但这不是重点。
  • 大多数编译器在编译代码时实际上并不与您进行对话:-)

I just noticed that ByteArrayOutputStream.write doesn't in fact declare IOException -- but Eclipse complains about an unhandled exception whenever I use it... strange.

That's easy to explain. You've probably done something like this:

    OutputStream os = new ByteArrayOutputStream();
    ...
    os.write();

The "problem" is that you are calling the method as OutputStream.write() rather than as ByteArrayOutputStream.write(). So the compiler says:

"Ah ... write() on an OutputStream can throw an IOException, so you gotta deal with it."

It cannot say:

"This particular OutputStream is really a ByteArrayOutputStream ... so we'll let you off."

because the JLS doesn't allow it.

This is one of those edge cases where following "best practice" by coding to the interface rather than the implementation class comes back to bite you.

OK so ...

  • its a gentle nip, not a full-on bite.
  • OutputStream is implemented as a Java class not a Java interface, but that is beside the point.
  • most compilers don't actually hold conversations with you while compiling your code :-)

浊酒尽余欢 2024-11-21 01:41:15

典型的陈词滥调是在 catch 块中抛出 new RuntimeException(theIOException)。如果不可能的事情发生了,你至少会发现它。

A typical cliche is to throw new RuntimeException(theIOException) in the catch block. If the impossible happens, you at least find out about it.

等待圉鍢 2024-11-21 01:41:15

在这种情况下,异常链是最佳实践。即抛出一个 RuntimeException。

Exception chaining is the best practice in this situation. i.e throw a RuntimeException.

时光暖心i 2024-11-21 01:41:15

自 2002 年以来,针对此问题有一个增强票据。原因这个问题没有得到解决,因为它会影响与以前的 java 版本的兼容性。

以下是我会考虑的两种解决方法。

解决方法 1

write(byte[], int, int) 方法不会引发已检查异常。指定 2 个附加参数会更加冗长。但总的来说,如果没有 try-catch,占用空间会更小。

baos.write(array, 0, array.length);

解决方法 2

另一种可能的解决方案是编写自己的ByteUtil,该类在内部捕获异常。

public final class ByteUtil
{
  public static void write(ByteArrayOutputStream baos, byte[] bytes)
  {
    try
    {
      baos.write(bytes);
    }
    catch (IOException e)
    {
      // impossible
    }
  }
}

// usage
ByteUtil.write(baos, bytes);

There is an enhancement ticket for this issue since 2002. The reason why this does not get fixed, is that it would impact compatibility with previous java versions.

Here follow 2 workarounds that I would consider.

Workaround 1

The write(byte[], int, int) method does not throw checked exceptions. It is a bit more verbose to specify the 2 additional parameters. But all by all the footprint is smaller without the try-catch.

baos.write(array, 0, array.length);

Workaround 2

Another possible solution, is to write your own ByteUtil class, which catches the exception internally.

public final class ByteUtil
{
  public static void write(ByteArrayOutputStream baos, byte[] bytes)
  {
    try
    {
      baos.write(bytes);
    }
    catch (IOException e)
    {
      // impossible
    }
  }
}

// usage
ByteUtil.write(baos, bytes);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文