Java中用内存映射处理大文件的实现代码_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
内存映射文件
java实现端口转发映射、java如何实现映射、java如何实现端口映射、java 内存映射文件、java 内存映射,以便于您获取更多的相关知识。

时间: 2024-11-10 07:53:20

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

Java中用内存映射处理大文件

在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如下为一个对比实验. package test;   import java.io.BufferedInputStream;   import java.io.FileInputStream;   import java.io.FileNotFoundException;   import java.

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

在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如下为一个对比实验. 复制代码 代码如下: package test;  import java.io.BufferedInputStream;  import java.io.FileInputStream;  import java.io.FileNotFoundException;  impor

内存映射修改大文件

本文介绍利用内存映射文件修改大文件:在大文件内存前加入一段数据,若要使用内存映射文件,必须执行下列操作步骤: 创建或打开一个文件内核对象,该对象用于标识磁盘上你想用作内存映射文件的文件: 创建一个文件映射内核对象,告诉系统该文件的大小和你打算如何访问该文件: 让系统将文件映射对象的全部或一部分映射到你的进程地址空间中: 当完成对内存映射文件的使用时,必须执行下面这些步骤将它清除: 告诉系统从你的进程的地址空间中撤消文件映射内核对象的映像: 关闭文件映射内核对象: 关闭文件内核对象: 下面将用一个

内存映射-读取大文件时遇到的问题

问题描述 读取大文件时遇到的问题 用readfile()函数也好,用内存映射的方式也好,怎么读取的数据都只是文件第一行?其他的都读取不到?不知道错在哪里,谢谢您的回答! 解决方案 应该要遍历去读取吧?不知道你怎么在弄... 解决方案二: 你可能只指定了第一行,没有遍历去指定行.把代码贴出来看看 解决方案三: 你是不是用了strtok. 它会把原字符串的分隔符替换成/0

java 通过apache ftp读取大文件或者下载大文件

问题描述 java 通过apache ftp读取大文件或者下载大文件 本人技术短,参照网上各位大侠的帖子写了登录ftp去读取ftp下面文件然后直接存进数据库的代码 ,但是我的代码只能读取一些小的文件,文件大点就报内存溢出.谁可以给个能在ftp上面下载大文件或者能够直接读取ftp服务器上面的大文件然后直接解析存进数据库的代码例子.不胜感激. 解决方案 内存溢出..说明内存方步下文件..ftp取到liu后写入文件吧...ps都内存溢出了..你不可能在内存中解析的..有可能是你jvm内存设置太小所致.

mongodb mmap内存映射是把文件中数据全部映射到内存中的吗?

问题描述 mongodb mmap内存映射是把文件中数据全部映射到内存中的吗? 资料上说:在Mongodb中,其使用了操作系统底层提供的内存映射机制,即MMAP.MMAP可以把磁盘文件的一部分或全部内容直接映射到内存,这样文件中的信息位置就会在内存中有对应的地址空间,这时对文件的读写可以直接用指针来做,而不需要read/write函数了.同时操作系统会将数据刷新保存到磁盘上. 我有个疑问:这个内存映射,是把文件中数据全部映射到内存中的吗?还是只是映射一部分内容,那么这部门内容又是什么的呢? 请专

Java实现按行读取大文件_java

Java实现按行读取大文件 String file = "F:" + File.separator + "a.txt"; FileInputStream fis = new FileInputStream(file); RandomAccessFile raf = new RandomAccessFile(new File(file),"r"); String s ; while((s =raf.readLine())!=null){ Syste

string-关于JAVA,用哪位大神能说说这代码是什么意思吗?

问题描述 关于JAVA,用哪位大神能说说这代码是什么意思吗? s = new String("EOL"); break; 解决方案 不知道这样问有什么意义 解决方案二: 新建一个String对象s,并赋值为EOL,然后中断 解决方案三: 应该是for循环或者是switch中的语句,就是简单的字符串创建,创建一个值为EOF的字符串后跳出循环. 解决方案四: 可以理解为创建了两个对象 解决方案五: 你的代码就不能截的再短一点吗??? 解决方案六: 就是s="EOL" 结

Java如何高效的读取大文件实例教程

       1.概述 本教程将演示如何用Java高效地读取大文件,这些大文件操作虽然不是很常用,但是如果有项目要用到的话就有用武之地了. 2.在内存中读取 读取文件行的标准方式是在内存中读取,Guava 和Apache Commons IO都提供了如下所示快速读取文件行的方法: Files.readLines(new File(path), Charsets.UTF_8); FileUtils.readLines(new File(path)); 这种方法带来的问题是文件的所有行都被存放在内存