Java IO学习笔记三:MMAP与RandomAccessFile - Grey Zeng

博客园 · · 895 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

作者:Grey

原文地址:Java IO学习笔记三:MMAP与RandomAccessFile

关于RandomAccessFile

相较于前面提到的BufferedReader/Writer和FileReader/Writer

普通的ReaderWriter只能顺序读写数据,RandomAccessFile提供了一个独有的seek方法,可以修改文件内容的指针,从而可以方便读取和修改文件中的任意位置。示例:

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

import static java.nio.charset.StandardCharsets.UTF_8;

public class TestRandomAccessFile {

    public static void main(String[] args) {
        String path = "C:\\workspace\\out.txt";
        try {
            RandomAccessFile randomAccessFile = new RandomAccessFile(path, "rw");
            randomAccessFile.write("Hello xxxld".getBytes(UTF_8));
            randomAccessFile.seek(6);
            randomAccessFile.write("Wor".getBytes(UTF_8));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

seek(6)让指针跳到"Hello xxld"这个字符串中的第一个"x"的位置,再次写入"Wor"这个字符串(覆盖写)

所以返回的结果是:

Hello World

关于MMAP

关于mmap,可以参考这篇文章的介绍认真分析mmap:是什么 为什么 怎么用

mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。

以及从内核文件系统看文件读写过程

通过RandomAccessFile可以拿到文件的FileChannel,并做内存映射(底层就是MMAP,因为文件是块设备,可以来回自由寻址,所以只有FileChannel才能做内存映射),即:把内核的pagecache和文件的数据地址空间映射起来。


    public static void testRandomAccessFileIO() throws Exception {
        String path = "C:\\workspace\\out.txt";
        byte[] data = "1234567\n".getBytes();
        RandomAccessFile file = new RandomAccessFile(path, "rw");
        FileChannel channel = file.getChannel();
        int size = 4096 * 100;
        MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_WRITE, 0, size);
        while (size != 0) {
            map.put(data);
            size -= data.length;
        }
        map.force();
    }

其中

 channel.map(FileChannel.MapMode.READ_WRITE, 0, size);

通过mmap生成的且是堆外的和文件映射的内存区域

原先我们的FileWriter需要通过write方法才能将数据写入pagecache,现在只需要通过map.put方法即可。

其中

map.force()

方法就等同于File中的

file.flush()

方法

将内容从主存写入磁盘中。

源码

Github

本文来自:博客园

感谢作者:博客园

查看原文:Java IO学习笔记三:MMAP与RandomAccessFile - Grey Zeng

895 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传