内存映射文件处理大文件

先说结论:使用内存映射文件来处理大文件可以提高效率。

为什么呢?

我们先来看看如果不使用内存映射文件的处理流程是怎样的,首先我们得先读出磁盘文件的内容到内存中,然后修改,最后回写到磁盘上。第一步读磁盘文件是要经过一次系统调用的,它首先将文件内容从磁盘拷贝到内核空间的一个缓冲区,然后再将这些数据拷贝到用户空间,实际上是两次数据拷贝。第三步回写也一样也要经过两次数据拷贝。

所以我们基本上会有四次数据的拷贝了,因为大文件数据量很大,几十GB甚至更大,所以拷贝的开销是非常大的。

而内存映射文件是操作系统的提供的一种机制,可以减少这种不必要的数据拷贝,从而提高效率。它由mmap()将文件直接映射到用户空间,mmap()并没有进行数据拷贝,真正的数据拷贝是在缺页中断处理时进行的,由于mmap()将文件直接映射到用户空间,所以中断处理函数根据这个映射关系,直接将文件从硬盘拷贝到用户空间,所以只进行了一次数据拷贝
,比read进行两次数据拷贝要好上一倍,因此,内存映射的效率要比read/write效率高。

一般来说,read write操作可以满足大多数文件操作的要求,但是对于某些特殊应用领域所需要的几十GB甚至更大的存储,这种通常的文件处理方法进行处理显然是行不通的。目前,对于上述大文件的操作一般是以内存映射文件的方式来加以处理的。

内存映射,并不是将文件加载到内存。

内存映射首先申请一段地址空间,并映射到物理存储器,而这里的物理存储器就是文件所在的磁盘,类似虚拟内存(pagefile);

当有需要时,程序不需要先把它加到内存,而是直接从磁盘读取。从这里看,IO操作减少了(不需要先加载到内存)

使用内存映射文件,读取大文件

public static void main(String[] args) throws IOException {
List<String> res = new ArrayList<>();
File file = new File("C:\\Users\\7q\\Desktop\\LogStat_2017-05-15_000.log");
long length = file.length();
//new RandomAccessFile(file,mode);只读方式("r"),还是以读写方式("rw"),不只是只写方式
//fileChannel.map(FileChannel.MapMode mode, long position, long size),映射方式,从什么位置开始映射,映射的范围有多大
MappedByteBuffer buffer = new RandomAccessFile(file, "r").getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());
StringBuilder sb = new StringBuilder();
for (int i = 0; i < (int) length; i++) {
//buffer.get(i):返回对应索引的字节 \n的ASCII为10
if (buffer.get(i) == 10) {//判断遇到换行符,处理此行数据
res.add(sb.toString());
sb.delete(0, sb.length());
} else if (i == length - 1) {//判断到了最后一行,处理此行数据
sb.append((char) buffer.get(i));
res.add(sb.toString());
sb.append((char) buffer.get(i));
} else {//拼接成一行数据
sb.append((char) buffer.get(i));
}
}
for (String re : res) {
System.out.println(re);
}
}

null

时间: 2024-10-12 08:18:08

内存映射文件处理大文件的相关文章

Java NIO内存映射---上G大文件处理

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了java中内存映射的原理及过程,与传统IO进行了对比,最后,用实例说明了结果. 一.java中的内存映射IO和内存映射文件是什么? 内存映射文件非常特别,它允许Java程序直接从内存中读取文件内容,通过将整个或部分文件映射到内存,由操作系统来处理加载请求和写入文件,应用只需要和内存打交道,这使得IO操作非常快.加载内存映射文件所使用的内存在Java堆区之外.Java编程语言

Java NIO内存映射---上G大文件处理(转)

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了java中内存映射的原理及过程,与传统IO进行了对比,最后,用实例说明了结果. 一.java中的内存映射IO和内存映射文件是什么? 内存映射文件非常特别,它允许Java程序直接从内存中读取文件内容,通过将整个或部分文件映射到内存,由操作系统来处理加载请求和写入文件,应用只需要和内存打交道,这使得IO操作非常快.加载内存映射文件所使用的内存在Java堆区之外.Java编程语言

VC++ 中使用内存映射文件处理大文件

摘要: 本文给出了一种方便实用的解决大文件的读取.存储等处理的方法,并结合相关程序代码对具体的实现过程进行了介绍. 引言 文件操作是应用程序最为基本的功能之一,Win32 API和MFC均提供有支持文件处理的函数和类,常用的有Win32 API的CreateFile().WriteFile().ReadFile()和MFC提供的CFile类等.一般来说,以上这些函数可以满足大多数场合的要求,但是对于某些特殊应用领域所需要的动辄几十GB.几百GB.乃至几TB的海量存储,再以通常的文件处理方法进行处

【转】Python之mmap内存映射模块(大文本处理)说明

[转]Python之mmap内存映射模块(大文本处理)说明 背景: 通常在UNIX下面处理文本文件的方法是sed.awk等shell命令,对于处理大文件受CPU,IO等因素影响,对服务器也有一定的压力.关于sed的说明可以看了解sed的工作原理,本文将介绍通过python的mmap模块来实现对大文件的处理,来对比看他们的差异. 说明: mmap是一种虚拟内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系.关于系统中mm

Python之mmap内存映射模块(大文本处理)说明

背景: 通常在UNIX下面处理文本文件的方法是sed.awk等shell命令,对于处理大文件受CPU,IO等因素影响,对服务器也有一定的压力.关于sed的说明可以看了解sed的工作原理,本文将介绍通过python的mmap模块来实现对大文件的处理,来对比看他们的差异. 说明: mmap是一种虚拟内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系.关于系统中mmap的理论说明可以看百度百科和维基百科说明以及mmap函数介

将小文件合并大文件上传

自定义方法将本地多个小文件合并成一个大文件上传到HDFS上. package test; import java.net.URI; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FileStatus; impo

如何分发大文件、大文件传输解决方案

随着云计算.大数据技术不断发展,4K 视频.虚拟现实(VR).视频直播等互联网应用领域不断升级更新,企业网.数据中心规模持续扩大,企业拥有的数据急剧增长,海量文件随之产生. 同时,互联网时代,众多行业都面临大型文件传输的问题,速度慢,是否安全,是优先考虑的前提! 一直以来,企业通常使用QQ软件.FTP.网盘或拆分数据.快递硬盘等方式进行海量文件上传和下载. 但是这些方式存在很多弊端,导致企业不能有效利用海量文件: 通常的一些方法: 1.使用QQ等软件直接对传:这种方法在线随时都可以传,比较方便,

文件操作--大文件的加密和搬运

C文件操作综合项目: 读取一个文件的数据到另一个文件,在读取的过程中加密. #include "stdlib.h" #include "stdio.h" #include "string.h" int fileEnc(char* fileDestinationPath, char* fileSourcePath) { FILE *fileDestination = NULL; FILE *fileSource = NULL; int ret =

如何分发大文件、大文件传输解决方案-JS

前言:因自己负责的项目(jetty内嵌启动的SpringMvc)中需要实现文件上传,而自己对java文件上传这一块未接触过,且对 Http 协议较模糊,故这次采用渐进的方式来学习文件上传的原理与实践.该博客重在实践. 一. Http协议原理简介 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且H