`

RandomAccessFile与内存映射文件

    博客分类:
  • Java
阅读更多

RandomAccessFile

RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了。这些记录的大小不必相同;但是其大小和位置必须是可知的。但是该类仅限于操作文件。

RandomAccessFile不属于InputStream和OutputStream类系的。实际上,除了实现DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个类系毫不相干,甚至不使用InputStream和OutputStream类中已经存在的任何功能;它是一个完全独立的类,所有方法(绝大多数都只属于它自己)都是从零开始写的。这可能是因为RandomAccessFile能在文件里面前后移动,所以它的行为与其它的I/O类有些根本性的不同。总而言之,它是一个直接继承Object的,独立的类。

基本上,RandomAccessFile的工作方式是,把DataInputStream和DataOutputStream结合起来,再加上它自己的一些方法,比如定位用的getFilePointer( ),在文件里移动用的seek( ),以及判断文件大小的length( )、skipBytes()跳过多少字节数。此外,它的构造函数还要一个表示以只读方式("r"),还是以读写方式("rw")打开文件的参数 (和C的fopen( )一模一样)。它不支持只写文件。

只有RandomAccessFile才有seek搜寻方法,而这个方法也只适用于文件。BufferedInputStream有一个mark( )方法,你可以用它来设定标记(把结果保存在一个内部变量里),然后再调用reset( )返回这个位置,但是它的功能太弱了,而且也不怎么实用。

RandomAccessFile的绝大多数功能,但不是全部,已经被JDK 1.4的nio的"内存映射文件(memory-mapped files)"给取代了,你该考虑一下是不是用"内存映射文件"来代替RandomAccessFile了。

import java.io.IOException;
import java.io.RandomAccessFile;

public class TestRandomAccessFile {
	public static void main(String[] args) throws IOException {
		RandomAccessFile rf = new RandomAccessFile("rtest.dat", "rw");
		for (int i = 0; i < 10; i++) {
			//写入基本类型double数据
			rf.writeDouble(i * 1.414);
		}
		rf.close();
		rf = new RandomAccessFile("rtest.dat", "rw");
		//直接将文件指针移到第5个double数据后面
		rf.seek(5 * 8);
		//覆盖第6个double数据
		rf.writeDouble(47.0001);
		rf.close();
		rf = new RandomAccessFile("rtest.dat", "r");
		for (int i = 0; i < 10; i++) {
			System.out.println("Value " + i + ": " + rf.readDouble());
		}
		rf.close();
	}
} 

内存映射文件

内存映射文件能让你创建和修改那些因为太大而无法放入内存的文件。有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问。这种解决办法能大大简化修改文件的代码。
fileChannel.map(FileChannel.MapMode mode, long position, long size)将此通道的文件区域直接映射到内存中。注意,你必须指明,它是从文件的哪个位置开始映射的,映射的范围又有多大;也就是说,它还可以映射一个大文件的某个小片断。


MappedByteBuffer是ByteBuffer的子类,因此它具备了ByteBuffer的所有方法,但新添了force()将缓冲区的内容强制刷新到存储设备中去、load()将存储设备中的数据加载到内存中、isLoaded()位置内存中的数据是否与存储设置上同步。这里只简单地演示了一下put()和get()方法,除此之外,你还可以使用asCharBuffer( )之类的方法得到相应基本类型数据的缓冲视图后,可以方便的读写基本类型数据。

import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class LargeMappedFiles {
	static int length = 0x8000000; // 128 Mb

	public static void main(String[] args) throws Exception {
		// 为了以可读可写的方式打开文件,这里使用RandomAccessFile来创建文件。
		FileChannel fc = new RandomAccessFile("test.dat", "rw").getChannel();
		//注意,文件通道的可读可写要建立在文件流本身可读写的基础之上
		MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, 0, length);
		//写128M的内容
		for (int i = 0; i < length; i++) {
			out.put((byte) 'x');
		}
		System.out.println("Finished writing");
		//读取文件中间6个字节内容
		for (int i = length / 2; i < length / 2 + 6; i++) {
			System.out.print((char) out.get(i));
		}
		fc.close();
	}
}
 

尽管映射写似乎要用到FileOutputStream,但是映射文件中的所有输出 必须使用RandomAccessFile,但如果只需要读时可以使用FileInputStream,写映射文件时一定要使用随机访问文件,可能写时要读的原因吧。

 

该程序创建了一个128Mb的文件,如果一次性读到内存可能导致内存溢出,但这里访问好像只是一瞬间的事,这是因为,真正调入内存的只是其中的一小部分,其余部分则被放在交换文件上。这样你就可以很方便地修改超大型的文件了(最大可以到2 GB)。注意,Java是调用操作系统的"文件映射机制"来提升性能的。

 

 

分享到:
评论

相关推荐

    Java NIO 应用使用内存映射文件实现进程间通信

    在Java NIO中,内存映射文件(MappedByteBuffer)是一个重要的特性,它允许将文件直接映射到内存中,以便于快速访问和修改文件内容。这一特性不仅提高了读写效率,而且还能用于进程间通信(IPC)。 内存映射文件的...

    【IT十八掌徐培成】Java基础第27天-01.MappedMemoryBuffer-文件内存映射缓冲区.zip

    1. **内存映射文件**:内存映射文件是一种技术,它将文件的内容直接映射到进程的虚拟地址空间中,使得文件就像一个巨大的字节数组一样可以被直接访问。这种方式减少了I/O操作的开销,因为操作系统负责文件和内存之间...

    Java中用内存映射处理大文件的实现代码

    对比实验中,我们使用了FileInputStream、BufferedInputStream以及RandomAccessFile分别进行文件读取,可以看到,使用内存映射文件(MappedByteBuffer)的读取速度通常会显著快于传统的I/O流,特别是在处理大文件时...

    Java中使用内存映射实现大文件上传实例

    2. **数据安全性**:由于内存映射文件与进程虚拟内存直接关联,程序崩溃可能会导致文件数据丢失。 3. **同步问题**:在多线程环境下,如果不加控制,可能会出现数据不一致的问题。 因此,在实际应用中,使用内存...

    java大文件读取-乔乐共享

    内存映射文件是一种特殊的文件处理方式,它能够将文件的一部分或者全部映射到内存地址空间中,从而允许程序像访问内存一样读写文件中的数据。这种方法特别适合处理大文件,因为它可以减少文件I/O操作,提高读写效率...

    java读取大文件

    为了有效地读取大文件,可以使用缓冲区(Buffer)和内存映射文件(MappedByteBuffer)技术。下面将详细解释如何使用这些技术以及代码中的关键部分。 1. **缓冲区(Buffer)**: Java中的缓冲区是用于提高数据读写...

    Java RandomAccessFile的用法详解

    虽然`RandomAccessFile`功能强大,但在某些情况下,内存映射文件可能更适合处理大文件,因为它提供了更高效的内存和I/O管理。然而,对于小文件和简单的随机访问,`RandomAccessFile`仍然是一个很好的选择。 总的来...

    java nio 包读取超大数据文件

    ### Java NIO 处理超大数据文件的知识点详解 ...综上所述,使用Java NIO处理超大数据文件时,关键是利用好内存映射文件技术和合理的数据读取策略,通过适当的分块和数据解析方法,可以有效地提升读取速度和处理能力。

    commons-mmf.rar_java nio_java共享内存_共享内存

    在Java中,可以通过`java.nio.MappedByteBuffer`类来实现共享内存功能,这被称为内存映射文件(Memory-Mapped File,MMF)。 `MappedByteBuffer`是NIO中的一种特殊缓冲区,它将文件的一部分映射到内存中,使得文件...

    java读取超大文本文件

    对于需要随机访问或文件特别大的情况,推荐使用`RandomAccessFile`和`FileChannel`的组合,特别是利用`MappedByteBuffer`进行内存映射文件读取。这种方式能够显著提高文件的读取速度,因为数据直接从磁盘映射到内存...

    读大文件Java

    `FileChannel`可以用来读写大文件,配合`MappedByteBuffer`实现内存映射文件,性能更优。 ```java FileChannel fc = FileChannel.open(Paths.get("largefile.txt"), StandardOpenOption.READ); MappedByteBuffer ...

    【IT十八掌徐培成】Java基础第26天-06.FileChannel-RandomAccessFile-CopyFile.zip

    `FileChannel`的主要特性包括读写文件、映射内存到文件、锁定文件区域等。通过`FileInputStream`, `FileOutputStream`, `ServerSocketChannel`, `SocketChannel`等可以获取`FileChannel`实例。例如,我们可以使用`...

    J2SE.development.code.MemMapFile.rar_Java编程_Java_

    在标题和描述中提到的“MemMapFile”是Java中的一种内存映射文件(Memory-Mapped File)技术,它允许我们将文件直接映射到虚拟内存中,从而高效地读写大文件。这种技术在处理大量数据时非常有用,因为它可以利用操作...

    有效率的读取大文件(2G)

    5. **内存映射文件**:Java的`MappedByteBuffer`实现了内存映射文件功能,它将文件的部分或全部映射到进程的虚拟内存空间,使得可以直接通过内存访问文件,避免了I/O操作。但是需要注意,如果文件过大,可能会导致...

    java读取大文件简单实例

    为了解决这个问题,Java提供了一种名为“内存映射文件”(Memory-Mapped File)的技术,它允许我们将文件的部分内容映射到虚拟内存中,从而实现大文件的高效读写。 内存映射文件通过`java.nio`包中的`...

    深入浅出MappedByteBuffer.pdf

    **MappedByteBuffer**是Java NIO中用于内存映射文件的工具,它允许将文件内容直接映射到Java虚拟机的内存中,从而提供高效的文件读写性能。相比于传统的IO操作,MappedByteBuffer避免了数据在用户空间和内核空间之间...

    java全栈工程师-java io

    内存映射文件是一种高效的数据处理方式,它可以将文件或部分文件的内容映射到内存中,从而可以直接通过内存地址访问文件内容,提高了文件访问的速度。Java中通过`FileChannel`的`map()`方法实现内存映射文件。 ### ...

    java NIO 写文件

    4. **内存映射文件**:`MappedByteBuffer`允许将文件直接映射到内存,提供了极高的读写速度。 然而,尽管Java NIO提供了很多优势,但在实际使用中,开发者还需要注意一些潜在的问题,如内存管理(缓冲区过大可能...

    java io读取文件

    8. **内存映射文件(Memory-Mapped File)** - Java的`MappedByteBuffer`类允许将文件映射到内存,使得文件操作如同访问内存一样快速,适合处理大型文件。 9. **大数据量文件读取策略** - **分块读取**:对于大...

    一个用JAVA写的清除EXE病毒文件的代码

    8. **内存映射文件**:虽然示例中没有使用,但考虑到病毒检测,可能会用到内存映射文件(Memory-Mapped Files)技术来高效地比较文件内容与病毒特征码。 9. **安全性限制**:此代码示例仅作为基础的病毒检测和清除...

Global site tag (gtag.js) - Google Analytics