缓冲的RandomAccessFile java

mar*_*ssi 19 java io file-io buffering random-access

RandomAccessFile对于随机访问文件非常慢.您经常阅读有关在其上实现缓冲层的信息,但是无法在线查找代码.

所以我的问题是:你们谁知道这个类的任何开源实现共享指针或共享你自己的实现?

如果这个问题会成为关于这个问题的有用链接和代码的集合,我很确定,很多人都会共享这个问题并且SUN从来没有正确解决这个问题.

请不要引用MemoryMapping,因为文件可能比Integer.MAX_VALUE大.

Edw*_*rzo 12

好吧,即使文件大于Integer.MAX_VALUE,我也没有理由不使用java.nio.MappedByteBuffer.

显然,您不会被允许为整个文件定义单个MappedByteBuffer.但是你可以让几个MappedByteBuffers访问文件的不同区域.

FileChannenel.map中的位置和大小的定义是long类型,这意味着您可以提供超过Integer.MAX_VALUE的值,您唯一需要注意的是缓冲区的大小不会大于Integer.MAX_VALUE .

因此,您可以像这样定义几个地图:

buffer[0] = fileChannel.map(FileChannel.MapMode.READ_WRITE,0,2147483647L);
buffer[1] = fileChannel.map(FileChannel.MapMode.READ_WRITE,2147483647L, Integer.MAX_VALUE);
buffer[2] = fileChannel.map(FileChannel.MapMode.READ_WRITE, 4294967294L, Integer.MAX_VALUE);
...
Run Code Online (Sandbox Code Playgroud)

总之,大小不能大于Integer.MAX_VALUE,但起始位置可以是文件中的任何位置.

在Book Java NIO中,作者Ron Hitchens说:

通过内存映射机制访问文件比使用传统方法读取或写入数据更有效,即使使用通道也是如此.不需要进行明确的系统调用,这可能非常耗时.更重要的是,操作系统的虚拟内存系统自动缓存内存页面.这些页面将使用系统内存进行缓存,并且不会占用JVM内存堆中的空间.

一旦内存页面生效(从磁盘引入),就可以以全硬件速度再次访问它,而无需再进行系统调用来获取数据.包含索引或经常引用或更新的其他部分的大型结构化文件可以从内存映射中获益匪浅.与文件锁定结合使用以保护关键部分并控制事务原子性时,您将开始了解如何充分利用内存映射缓冲区.

我真的怀疑你会发现第三方API做得比这更好.也许您可能会发现在此体系结构之上编写的API以简化工作.

难道你不认为这种方法对你有用吗?


sbr*_*ges 12

您可以使用类似的代码从RandomAccessFile创建BufferedInputStream,

 RandomAccessFile raf = ...
 FileInputStream fis = new FileInputStream(raf.getFD());
 BufferedInputStream bis = new BufferedInputStream(fis);
Run Code Online (Sandbox Code Playgroud)

有些事情需要注意

  1. 关闭FileInputStream将关闭RandomAccessFile,反之亦然
  2. RandomAccessFile和FileInputStream指向相同的位置,因此从FileInputStream读取将提升RandomAccessFile的文件指针,反之亦然

可能你想要使用它的方式是这样的,

RandomAccessFile raf = ...
FileInputStream fis = new FileInputStream(raf.getFD());
BufferedInputStream bis = new BufferedInputStream(fis);

//do some reads with buffer
bis.read(...);
bis.read(...);

//seek to a a different section of the file, so discard the previous buffer
raf.seek(...);
bis = new BufferedInputStream(fis);
bis.read(...);
bis.read(...);
Run Code Online (Sandbox Code Playgroud)

  • 我采用了类似的方法,使用`getFD`方法.但是,我没有构建BufferedInputStream,而是构建了FileReader,然后构建了BufferedReader.这使我能够访问比readAccessFile提供的更快(并且可能更多UTF友好?)的`readLine`方法. (6认同)
  • @JeffTerrellPh.D. 我尝试了 BufferedReader 并注意到即使在多次调用 BufferedReader.readLine() 方法之后 RandomAccessFile.getFilePointer 方法也会返回相同的位置。这可能是因为 BufferedReader 可能会在一次对 readLine() 的调用中在内部将文件指针提前很远。 (2认同)