执行此操作时出现编译错误:
RandomAccessFile raf = new RandomAccessFile(...)
InputStream is = (InputStream)raf;
RandomAccessFile
应该是InputStream
的子类,尽管不是直接的。
来自docs:
RandomAccessFile
实施了DataInput
&{ DataInputstream
为什么这个无效?
同时感谢您就使用InputStream
作为RandomAccessFile
的正确方法提出意见?
我正在考虑包装方法。
答案 0 :(得分:43)
使用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());
答案 1 :(得分:16)
RandomAccessFile
扩展Object
, 扩展InputStream
。
如果你想从InputStream
获得RandomAccessFile
,我认为实施包装类是你最简单的选择。幸运的是,InputStream
的唯一抽象方法是read()
。
RandomAccessFile实现DataInput,其中包含DataInputstream&的InputStream
DataInputStream
是InputStream
的子类,也恰好实现DataInput
。继承和接口实现树如下所示:
InputStream DataInput
\ / \
\ / \
\ / \
DataInputStream RandomAccessFile
您可以在任何可以使用DataInputStream
或InputStream
的地方使用DataInput
。您可以在任何可以使用RandomAccessFile
的地方使用DataInput
。
但是你不能在继承层次结构中继续使用强制转换。特别是,将类转换为子类(或实现的接口)将引发ClassCastException
,除非该对象恰好是子类的实例。
尽管两个类恰好扩展Object
并不意味着它们可以互换。
答案 2 :(得分:4)
RandomAccessFile应该扩展InputStream,尽管不是 直接
不,不是。见Javadoc。
来自docs:
RandomAccessFile
实施DataInput
,DataInputstream
&InputStream.
根本不是'来自文档'。你搞定了。你所写的内容甚至没有意义。 DataInput
是一个界面。 DataInputStream
和InputStream
是类。接口不实现或扩展类。
Javadoc实际上说的是RandomAccessFile
扩展java.lang.Object
并实现Closeable, DataInput, DataOutput
。
答案 3 :(得分:3)
要建立@ robert-christian的答案,使用seek
开始的主要原因是skip
到某个位置,而不是来自{{1}的FileInputStream
ping字节}}。但那么为什么要使用前NIO API呢?
try (FileChannel ch = FileChannel.open(Paths.get(…), StandardOpenOption.READ)) {
InputStream is = Channels.newInputStream(ch.position(…));
// …
}