🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 10.3 本身的缺陷:`RandomAccessFile` `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()`重设那个位置。但这些做法都存在限制,并不是特别有用。