RandomAccessFile
用于包含了已知长度记录的文件,以便我们能用seek(
)从一条记录移至另一条;然后读取或修改那些记录。各记录的长度并不一定相同;只要知道它们有多大以及置于文件何处即可。
首先,我们有点难以相信RandomAccessFile
不属于InputStream
或者OutputStream
分层结构的一部分。除了恰巧实现了DataInput
以及DataOutput
(这两者亦由DataInputStream
和DataOutputStream
实现)接口之外,它们与那些分层结构并无什么关系。它甚至没有用到现有InputStream
或OutputStream
类的功能——采用的是一个完全不相干的类。该类属于全新的设计,含有自己的全部(大多数为固有)方法。之所以要这样做,是因为RandomAccessFile
拥有与其他IO类型完全不同的行为,因为我们可在一个文件里向前或向后移动。不管在哪种情况下,它都是独立运作的,作为Object
的一个“直接继承人”使用。
从根本上说,RandomAccessFile
类似DataInputStream
和DataOutputStream
的联合使用。其中,getFilePointer()
用于了解当前在文件的什么地方,seek()
用于移至文件内的一个新地点,而length()
用于判断文件的最大长度。此外,构造器要求使用另一个参数(与C的fopen()
完全一样),指出自己只是随机读("r"
),还是读写兼施("rw"
)。这里没有提供对“只写文件”的支持。也就是说,假如是从DataInputStream
继承的,那么RandomAccessFile
也有可能能很好地工作。
还有更难对付的。很容易想象我们有时要在其他类型的数据流中搜索,比如一个ByteArrayInputStream
,但搜索方法只有RandomAccessFile
才会提供。而后者只能针对文件才能操作,不能针对数据流操作。此时,BufferedInputStream
确实允许我们标记一个位置(使用mark()
,它的值容纳于单个内部变量中),并用reset()
重设那个位置。但这些做法都存在限制,并不是特别有用。