为什么不能将 RandomAccessFile 转换为 Inputstream?

发布于 2025-01-05 09:44:39 字数 485 浏览 0 评论 0原文

当我执行此转换时,出现编译错误:

RandomAccessFile raf = new RandomAccessFile(...)
InputStream is = (InputStream)raf;

RandomAccessFile 应该是 InputStream 的子类,尽管不是直接子类。

来自文档:

RandomAccessFile 实现了 DataInput ,它反过来 DataInputstream & InputStream

为什么这是无效的?

另外,感谢您对使用 RandomAccessFile 作为 InputStream 的正确方法提出意见?

我正在考虑包装方法。

I get compilation error when I do this cast:

RandomAccessFile raf = new RandomAccessFile(...)
InputStream is = (InputStream)raf;

RandomAccessFile is supposed to subclass InputStream although not directly.

From docs:

RandomAccessFile implements DataInput which inturn DataInputstream & InputStream

Why is this invalid?

Also appreciate your input on what would be the right way to use the RandomAccessFile as InputStream?

I am thinking of wrapper approach.

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

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

发布评论

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

评论(4

要走就滚别墨迹 2025-01-12 09:44:39

使用 Channels 实用程序类可以轻松实现这一点...

// STEP 1:  Create random access file read-only
RandomAccessFile raf = new RandomAccessFile("/text.txt", "r");

// STEP 2:  Use Channels to convert to InputStream
InputStream is = Channels.newInputStream(raf.getChannel());

This is easily achievable using the Channels utility class...

// STEP 1:  Create random access file read-only
RandomAccessFile raf = new RandomAccessFile("/text.txt", "r");

// STEP 2:  Use Channels to convert to InputStream
InputStream is = Channels.newInputStream(raf.getChannel());
夏末染殇 2025-01-12 09:44:39

RandomAccessFile 扩展对象,并且扩展InputStream

如果您想从 RandomAccessFile 获取 InputStream 我认为实现包装类是您最简单的选择。幸运的是,InputStream 的唯一抽象方法是read()

RandomAccessFile 实现了 DataInput,它返回 DataInputstream &输入流

DataInputStreamInputStream 的子类,它也恰好实现了 DataInput。继承和接口实现树如下所示:

           InputStream      DataInput
               \              /   \
                \            /     \
                 \          /       \
                DataInputStream   RandomAccessFile

您可以在任何可以使用 InputStreamDataInput 的地方使用 DataInputStream。您可以在任何可以使用 DataInput 的地方使用 RandomAccessFile

但是您不能像这样使用强制转换在继承层次结构中向上然后向下移动。特别是,将类转换为子类(或实现的接口)将引发 ClassCastException ,除非该对象恰好是子类的实例。

即使两个类碰巧扩展了Object,但这并不意味着它们是可以互换的。

RandomAccessFile extends Object, and does not extend InputStream.

If you want get an InputStream from a RandomAccessFile I think implementing a wrapper class is your simplest bet. Luckily the only abstract method of InputStream is read().

RandomAccessFile implements DataInput which inturn DataInputstream & InputStream

DataInputStream is a subclass of InputStream, which also happens to implement DataInput. The inheritance and interface implementation tree looks like this:

           InputStream      DataInput
               \              /   \
                \            /     \
                 \          /       \
                DataInputStream   RandomAccessFile

You could use a DataInputStream anywhere where you could use an InputStream or a DataInput. You could use a RandomAccessFile anywhere where you could use a DataInput.

But you can't go up and then down in the inheritance hierarchy like this using casts. In particular, casting a class to a subclass (or an interface to an implementation) will raise a ClassCastException unless the object happens to be an instance of the child class.

Even though two classes happen to extend Object that doesn't mean they are interchangeable.

少女情怀诗 2025-01-12 09:44:39

为了以@robert-christian的答案为基础,首先使用RandomAccessFile的主要原因是seek到某个位置,而不是skipping来自 FileInputStream 的字节。但那为什么还要费心使用 pre-NIO API呢?

try (FileChannel ch = FileChannel.open(Paths.get(…), StandardOpenOption.READ)) {
    InputStream is = Channels.newInputStream(ch.position(…));
    // …
}

To build on @robert-christian’s answer, the main reason to use RandomAccessFile to begin with is to seek to some position, rather than skipping bytes from a FileInputStream. But then why bother with pre-NIO APIs at all?

try (FileChannel ch = FileChannel.open(Paths.get(…), StandardOpenOption.READ)) {
    InputStream is = Channels.newInputStream(ch.position(…));
    // …
}
心奴独伤 2025-01-12 09:44:39

RandomAccessFile 应该扩展 InputStream,尽管不是
直接。

不,不是。请参阅 Javadoc。

来自文档:

RandomAccessFile 实现 DataInput ,而 DataInputstream 又实现了 DataInputstream输入流。

这根本不是“来自文档”。你做到了。你写的根本没有意义。 DataInput 是一个接口。 DataInputStreamInputStream 是类。接口不实现或扩展类。

Javadoc 实际上说的是 RandomAccessFile 扩展了 java.lang.Object 并实现了 Closeable、DataInput、DataOutput

RandomAccessFile is supposed to extends InputStream although not
directly.

No it isn't. See the Javadoc.

From docs:

RandomAccessFile implements DataInput which in turn DataInputstream & InputStream.

That's not 'from the docs' at all. You made it up. What you've written doesn't even make sense. DataInput is an interface. DataInputStream and InputStream are classes. Interfaces don't implement, or extend, classes.

What the Javadoc actuallys says is that RandomAccessFile extends java.lang.Object and implements Closeable, DataInput, DataOutput.

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