Java中用内存映射处理大文件
在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如下为一个对比实验。
- package test;
- import java.io.BufferedInputStream;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.RandomAccessFile;
- import java.nio.MappedByteBuffer;
- import java.nio.channels.FileChannel;
- public class Test {
- public static void main(String[] args) {
- try {
- FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
- int sum=0;
- int n;
- long t1=System.currentTimeMillis();
- try {
- while((n=fis.read())>=0){
- sum+=n;
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- long t=System.currentTimeMillis()-t1;
- System.out.println("sum:"+sum+" time:"+t);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- try {
- FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
- BufferedInputStream bis=new BufferedInputStream(fis);
- int sum=0;
- int n;
- long t1=System.currentTimeMillis();
- try {
- while((n=bis.read())>=0){
- sum+=n;
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- long t=System.currentTimeMillis()-t1;
- System.out.println("sum:"+sum+" time:"+t);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- MappedByteBuffer buffer=null;
- try {
- buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244);
- int sum=0;
- int n;
- long t1=System.currentTimeMillis();
- for(int i=0;i<1253244;i++){
- n=0x000000ff&buffer.get(i);
- sum+=n;
- }
- long t=System.currentTimeMillis()-t1;
- System.out.println("sum:"+sum+" time:"+t);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
测试文件为一个大小为1253244字节的文件。测试结果:
sum:220152087 time:1464
sum:220152087 time:72
sum:220152087 time:25
说明读数据无误。删去其中的数据处理部分。
- package test;
- import java.io.BufferedInputStream;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.RandomAccessFile;
- import java.nio.MappedByteBuffer;
- import java.nio.channels.FileChannel;
- public class Test {
- public static void main(String[] args) {
- try {
- FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
- int sum=0;
- int n;
- long t1=System.currentTimeMillis();
- try {
- while((n=fis.read())>=0){
- //sum+=n;
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- long t=System.currentTimeMillis()-t1;
- System.out.println("sum:"+sum+" time:"+t);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- try {
- FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
- BufferedInputStream bis=new BufferedInputStream(fis);
- int sum=0;
- int n;
- long t1=System.currentTimeMillis();
- try {
- while((n=bis.read())>=0){
- //sum+=n;
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- long t=System.currentTimeMillis()-t1;
- System.out.println("sum:"+sum+" time:"+t);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- MappedByteBuffer buffer=null;
- try {
- buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244);
- int sum=0;
- int n;
- long t1=System.currentTimeMillis();
- for(int i=0;i<1253244;i++){
- //n=0x000000ff&buffer.get(i);
- //sum+=n;
- }
- long t=System.currentTimeMillis()-t1;
- System.out.println("sum:"+sum+" time:"+t);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
测试结果:
sum:0 time:1458
sum:0 time:67
sum:0 time:8
由此可见,将文件部分或者全部映射到内存后进行读写,速度将提高很多。
这是因为内存映射文件首先将外存上的文件映射到内存中的一块连续区域,被当成一个字节数组进行处理,读写操作直接对内存进行操作,而后再将内存区域重新映射到外存文件,这就节省了中间频繁的对外存进行读写的时间,大大降低了读写时间。
Java中用内存映射处理大文件的更多相关文章
- Java使用内存映射实现大文件的上传
在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如 ...
- Delphi 中内存映射对于大文件的使用
这篇文章主要介绍了Delphi 中内存映射对于大文件的使用的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下 Delphi 中内存映射对于大文件的使用 平时很少使用大文件的内存映射,碰巧遇到了 ...
- Java NIO内存映射---上G大文件处理(转)
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了java中内存映射的原理及过程,与传统IO进行了对比,最后,用实例说明了结果 ...
- Java NIO 内存映射文件
Java NIO 内存映射文件 @author ixenos 文件操作的四大方法 前提:内存的访问速度比磁盘高几个数量级,但是基本的IO操作是直接调用native方法获得驱动和磁盘交互的,IO速度限制 ...
- Java利用内存映射文件实现按行读取文件
我们知道内存映射文件读取是各种读取方式中速度最快的,但是内存映射文件读取的API里没有提供按行读取的方法,需要自己实现.下面就是我利用内存映射文件实现按行读取文件的方法,如有错误之处请指出,或者有更好 ...
- JAVA NIO 内存映射(转载)
原文地址:http://blog.csdn.net/fcbayernmunchen/article/details/8635427 Java类库中的NIO包相对于IO 包来说有一个新功能是内存 ...
- 如何设置Java虚拟机内存以适应大程序的装载
Java虚拟机对于运行时的程序所占内存是有限制的,当我们的项目或者程序很大时,往往会照成内存溢出. 举个例子: public class SmallTest1 { public static void ...
- java 通过内存映射文件来提高IO读取文件性能
MappedByteBuffer out = new RandomAccessFile("src/demo20/test.dat", "rw"). getCha ...
- php 如何在有限的内存中读取大文件
突然遇到了一个要读取超过80M文件的需求,很悲剧的,不管是file_get_content还是file什么的,都会将读取的文件一次性加载到内存中. 正常情况下,我们可以使用fseek来读取,好处就是不 ...
随机推荐
- Emit学习(1) - HelloWorld
之前看过Dapper(使用到了Emit), CYQ.Data(另一种思路,没有使用Emit)类的框架之后, 也想自己做一个小框架玩一下, 不过此时能力太过欠缺, 做不了Cyq.Data或者PDF.Ne ...
- C#常用类库
1.0 TimeSpan TimeSpan passTime = (TimeSpan)(DateTime.Now - curUser.refuseTime); if (passTime.Days * ...
- Dapper小型ORM的使用(随便吐槽下公司)
近来公司又有新项目要做,之前做项目用过蛮多ORM,包括ef,NetTiers,ServiceStack.OrmLite等ROM,每种ORM都有一定的坑(或者说是使用者的问题吧~~).用来用去都觉的有一 ...
- MVP的PV模式与SC模式
MVC是现今挺被推崇的一种架构模式,而MVP在MVC的基础对视图与模型上再解耦,使结构和各自的功能也有所改变.在去年鄙人也尝试了一下使用MVP做了一个小Demo,作为了MVC的一个变体,MVP还分了两 ...
- C#编程总结(一)序列化
C#编程总结(一)序列化 序列化是将对象状态转换为可保持或传输的格式的过程.与序列化相对的是反序列化,它将流转换为对象.这两个过程结合起来,可以轻松地存储和传输数据. 几种序列化技术: 1) ...
- C# IDisposable接口
public class MyClass : IDisposable { public int a; public MyClass() { //构造 } public void Dispose() { ...
- Delphi Berlin 10.1 for iOS 成生 info.plist 顺序改变了
在 Delphi Seattle 10 update 1 版本(含之前版本),只要 Project > Build 会立即生成 info.plist 如果需要修改 info.plist 可以利用 ...
- web工程依赖的问题
http://blog.csdn.net/testcs_dn/article/details/43764497 做个记录
- IT职业思考 谈谈IT外包公司
个人能力强才是王道 1. 为什么像BAT.HP.IBM.华为这些大公司还需要外包,他们已经有那么多的技术人员 一个公司,如果没有那么多项目,光养这些技术人员,实际的经营成本确实不低,但是这些技术人员又 ...
- CI框架源码阅读笔记8 控制器Controller.php
最近时间有些紧,源码阅读系列更新有些慢.鉴于Controller中代码比较少,本次Blog先更新该文件的源码分析. 在经过路由分发之后,实际的应用Controller接管用户的所有请求,并负责与用户数 ...