`
bjxagu
  • 浏览: 165925 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

用内存映射文件创建和修改那些大到无法读入内存的文件

阅读更多

 有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问了。这种解决思路能大大简化修改文件的代码。下面就是一个简单的例子:

代码
  1. import java.io.*;  
  2. import java.nio.*;  
  3. import java.nio.channels.*;  
  4. public class LargeMappedFiles {  
  5.   static int length = 0x8FFFFFF// 128 Mb  
  6.   public static void main(String[] args) throws Exception {  
  7.     MappedByteBuffer out =   
  8.       new RandomAccessFile("test.dat""rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, length);  
  9.     for(int i = 0; i < length; i++)  
  10.       out.put((byte)'x');  
  11.     System.out.println("Finished writing");  
  12.     for(int i = length/2; i < length/2 + 6; i++)  
  13.       System.out.print((char)out.get(i));  
  14.   }  
  15. }  
<script type="text/javascript"></script>     为了能以读写的方式打开文件,我们从RandomAccessFile入手。

    拿到channel之后,我们用map( )方法生成了一个MappedByteBuffer。这是一种特殊的"direct buffer"。注意,你必须指明,它是从文件的哪个位置开始映射的,映射的范围又有多大;也就是说,它还可以映射一个大文件的某个小片断。

   MappedByteBuffer是ByteBuffer的派生类,因此它具备了ByteBuffer的所有方法。这里只简单地演示了一下put( )和get( )方法,除此之外,你还可以使用asCharBuffer( )之类的方法。

    上述例程创建了一个128MB的文件,或许这已经超出OS的允许范围了。文件的访问好像只是一瞬间的事,这是因为,真正调入内存的只是其中的一小部分,其余部分则被放在交换文件上。这样你就可以很方便地修改超大型的文件了(最大可以到2 GB)。

 

注意,Java是调用操作系统的"文件映射机制(file-mapping facility)"来提升性能的。

由于Java的文件锁是直接映射操作系统的锁机制的,因此其它进程也能看到文件锁。

虽然你可以用wrap( ) 直接把char数组转换成CharBuffer,但实际上它还是一个ByteBuffer,而CharBuffer只是它的view。由此可知,我们操控的对象永远都是ByteBuffer,因为只有它才能往channel里读写数据

一般来说,你是不会让两个进程去共享一个网络socket的。)tryLock( ) 是非阻塞的。它会试着去获取这个锁,但是如果得不到(其它进程已经以独占方式得到这个锁了),那它就直接返回。而lock( )是阻塞的。如果得不到锁,它会在一直处于阻塞状态,除非它得到了锁,或者你打断了调用它(即lock( )方法)的线程,或者关闭了它要lock( )的channel,否则它是不会返回的。最后用FileLock.release( )释放锁。

还可以像这样锁住文件的某一部分

tryLock(long position, long size, boolean shared)
或者

lock(long position, long size, boolean shared)
这个方法能锁住文件的某个区域(size - position)。
其中第三个参数表示锁能不能共享。
虽 然在修改文件的过程中,无参数的lock( )和tryLock( )方法的锁定范围会随文件大小的变化,带参数的方法却不行。如果你锁住了position到position+size这段范围,而文件的长度又增加了, 那么position+size后面是不加锁的。而无参数的lock方法则会锁定整个文件,不管它变不变长。

锁是独占的还是共享的,这要由操作系统来决定。如果操作系统不支持共享锁,而程序又申请了一个,那么它会返回一个独占锁。你可以用FileLock.isShared( )来查询锁的类型(共享还是独占)。


分享到:
评论

相关推荐

    内存映射文件(学习资料)

    - **加载和执行可执行文件和DLL**:系统使用内存映射文件加载和执行`.exe`和`DLL`文件,这不仅节省了页文件的空间,还减少了应用程序启动所需的时间。 - **访问磁盘数据文件**:可以通过内存映射文件访问磁盘上的...

    关于UNIX上文件映射技术的学习报告

    - 为了确保内存映射区与磁盘文件的一致性,可以使用`msync`函数: ```c int msync(void *addr, size_t len, int flags); ``` - `addr`和`len`:与`munmap`中的参数相同,表示要同步的内存区域。 - `flags`:...

    易语言 - 内存中加载运行EXE源码

    方法二:使用“内存映射文件”和“虚拟内存操作” 另一种方法是将EXE文件加载到内存中,然后通过内存映射和虚拟内存操作来执行。首先,你需要使用“读文件”命令将EXE文件内容读入内存,然后找到PE(Portable ...

    在内存中运行EXE可执行文件 delphi

    5. **内存映射**:使用`CreateFileMapping`和`MapViewOfFile`函数将文件内容映射到进程的虚拟内存中,这样可以减少I/O操作。 6. **进程创建与执行**:使用`CreateProcess`或`CreateProcessAsUser` API启动新进程,...

    matlab的mmap

    - **关闭和释放**:使用`fclose`函数关闭内存映射文件,释放占用的内存资源。 3. **优势与适用场景**: - **高效性**:内存映射特别适合于大数据处理,因为它避免了频繁的磁盘I/O操作,提高了处理速度。 - **...

    操作系统课件:Lecture14 文件系统.ppt

    本课件主要介绍了文件系统的几个核心概念,包括文件的创建、删除、打开、关闭、读、写等传统访问接口,以及内存映射文件访问方式,同时涉及了文件保护机制,如口令、数据加密和访问控制。 6. 文件访问系统调用: 在...

    通过模拟文件操作命令的执行

    2. **读取和写入**:`read`命令将文件内容从磁盘读入内存,而`write`则将内存中的数据写入磁盘。这两个操作需要考虑缓存策略,如缓冲区的使用,以提高性能。同时,文件的读写还需要处理并发问题,防止数据不一致。 ...

    从内存中加载并启动一个exe1

    1. **将你的程序读入内存**:这是整个过程的第一步,需要将要启动的exe文件内容读取到内存的一个特定区域,通常是动态分配的内存空间。 2. **以CREATE_SUSPENDED模式启动svchost.exe**:调用`CreateProcess`函数,...

    opengl读入3ds

    可以使用鼠标输入和键盘输入来修改模型视图矩阵,以实现这些交互功能。 一个完整的读取3DS文件的例子会涵盖以上所有步骤,并提供详细的代码示例,解释如何将3DS文件的数据转换为OpenGL可理解的格式,并在屏幕上渲染...

    API之网络函数---整理网络函数及功能

    SetFileTime 设置文件的创建、访问及上次修改时间 SetHandleCount 这个函数不必在win32下使用;即使使用,也不会有任何效果 SetVolumeLabel 设置一个磁盘的卷标(Label) SystemTimeToFileTime 根据一个FILETIME...

    手写Hibernate 步骤(图,文字)以及原因

    - 切换到MyEclipse的Java Enterprise视图,为项目创建包,比如`db`,并在Database Explorer中生成DAO类和映射文件。 - 生成的DAO类(如`ComUser.java`)和映射文件(如`ComUser.hbm.xml`)将直接用于与数据库的...

    2008:操作系统(A)1

    操作系统会将被访问的页从磁盘读入内存,并进行相应的页面替换。 17. **设备作为文件操作的好处**:通过将外部设备模拟为文件,用户可以使用标准的文件操作来访问设备,简化编程接口,提高兼容性。 18. **打开文件...

    操作系统复习资料

    - **定义**: 虚拟存储器是一种技术,通过将部分内存空间映射到磁盘上,使得程序可以在比实际物理内存更大的地址空间中运行。 - **优势**: 提高了内存的使用效率,增加了可用的地址空间,增强了系统的灵活性和可扩展...

    读取并显示位图,直接操纵显示图像数组中的每一位像素

    3. 分配内存来存储位图数据,然后使用`CreateDIBSection`函数创建一个DIB(设备无关位图),将位图数据读入到这个DIB中。 4. 获取`StretchDIBits`所需的参数,包括源位图信息结构(BITMAPINFO)和位图数据指针。 5. ...

    Excel导入导出封装

    导入是指将外部数据源(如CSV文件、数据库记录等)读入到Excel工作表中,而导出则是将Excel中的数据保存到其他格式或位置,以便于分享或进一步处理。在编程中,这通常涉及到文件I/O操作和数据转换。 在Office 2003...

    python标准库中文版

    提供了内存映射文件的支持,可以在不读入整个文件的情况下访问其内容。 #### UserDict模块、UserList模块、UserString模块 提供了可定制的字典、列表和字符串容器,便于创建具有特定行为的容器类型。 #### ...

    三维地图编辑加载3DSLoader(OpengL,Directx)

    3DSLoader可能通过解析3DS文件的结构,将模型的顶点、面、纹理坐标、材质信息等数据读入内存,并创建相应的OpenGL或DirectX对象。在程序运行时,用户可以编辑这些三维地图,例如改变视角、缩放、旋转模型,或者修改...

    VC++6.0环境下 简单的职工管理系统 课程设计.doc

    - 职工信息以文件形式存储,程序执行时会先将文件全部读入内存,所有操作都在内存中完成,避免了内外存交换带来的性能影响。 - 文件存储的格式通常为文本,便于人阅读和编辑,同时易于实现基本的文件操作,如读取...

Global site tag (gtag.js) - Google Analytics