缓冲的RandomAccessFile java

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

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

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

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

好吧,即使文件大于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); ... 

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

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

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

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

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

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

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

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

有些事情需要注意

  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 aa different section of the file, so discard the previous buffer raf.seek(...); bis = new BufferedInputStream(fis); bis.read(...); bis.read(...); 

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

嗯,有可能在网上找到。
首先,jpeg2000中的JAI源代码有一个实现,以及更加无阻碍的内容: http : //www.unidata.ucar.edu/software/netcdf-java/

的javadoc:

http://www.unidata.ucar.edu/software/thredds/v4.3/netcdf-java/v4.0/javadoc/ucar/unidata/io/RandomAccessFile.html

如果您在64位计算机上运行,​​那么内存映射文件是您最好的方法。 只需将整个文件映射到一个大小相等的缓冲区数组中,然后根据需要为每个记录选择一个缓冲区(例如, edalorzo的答案,但是你需要重叠的缓冲区,这样你就不会有跨越边界的记录)。

如果您在32位JVM上运行,那么您将无法使用RandomAccessFile 。 但是,您可以使用它来读取包含整个记录的byte[] ,然后使用ByteBuffer从该数组中检索单个值。 在最坏的情况下,您应该进行两次文件访问:一次用于检索记录的位置/大小,另一次用于检索记录本身。

但是,请注意,如果您创建了大量的byte[] ,则可以开始强调垃圾回收器,如果您在整个文件中反弹,则会保持IO限制。