`

NIO中的内存映射文件使用对效率提高的验证

 
阅读更多

 对比较大的而不能放入内存的文件进行I/O操作时,如果使用NIO中的内存映射文件对性能效率和速度的提高是非常显著的。首先需要获取文件的通道,然后调用通道的map(FileChannel.MapMode mode,long position,long size)函数将文件从position位置开始的长度为size的内容映射到内存中。具体的效率比较代码示例如下:

 

Java代码  收藏代码
  1. import java.io.BufferedInputStream;  
  2. import java.io.BufferedOutputStream;  
  3. import java.io.DataInputStream;  
  4. import java.io.DataOutputStream;  
  5. import java.io.FileInputStream;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8. import java.io.RandomAccessFile;  
  9. import java.nio.IntBuffer;  
  10. import java.nio.channels.FileChannel;  
  11.   
  12. //测试代码是借用thingking in java中的  
  13. public class MappedIO {  
  14.       
  15.     //先声明需要写入的文件的内容的大小  
  16.     private static final int NUMOFINT=4000000;  
  17.     private static final int NUMOFOUT=2000000;  
  18.       
  19.     //测试类,用来测试使用普通的I/O操作和使用内存文件映射时速度的差别  
  20.     abstract static class Tester{  
  21.         private String name;  
  22.         public Tester(String name){  
  23.             this.name=name;  
  24.         }  
  25.           
  26.         public void runTest(){  
  27.             System.out.println("使用"+name+"所消耗的时间:");  
  28.             try{  
  29.             //以毫微秒为单位获取测试函数开始前的时间  
  30.             long begin=System.nanoTime();  
  31.               
  32.             test();  
  33.             //将测试函数结束后的系统的时间减去开始之前的时间获取  
  34.             double duration=System.nanoTime()-begin;  
  35.             //PrintStream中的使用指定格式字符串和参数将格式化字符串写入此输出流中的方法  
  36.             System.out.format("%.2f\n", duration/1.0e9);  
  37.             }catch(IOException e){  
  38.                 e.printStackTrace();  
  39.             }  
  40.         }  
  41.           
  42.         //具体的测试函数中其实不仅有对文件进行读取或写入的时间,还包括消耗的各种初始化I/O对象的时间,而且内存映射文件的初始化对象消耗更要比普通的操作大  
  43.         public abstract void test() throws IOException;  
  44.     }  
  45.       
  46.     private static Tester[] tests={  
  47.         //先使用普通的stream write,并且还是用了Buffered缓冲  
  48.         new Tester("stream write"){  
  49.             public void test()throws IOException{  
  50.                 DataOutputStream dos=new DataOutputStream(new BufferedOutputStream(new FileOutputStream("baolei.txt")));   
  51.                 for(int i=0;i<NUMOFINT;i++){  
  52.                     dos.writeInt(i);  
  53.                 }  
  54.                 dos.close();  
  55.             }  
  56.         },  
  57.         //使用内存映射文件方式写入文件时的测试内部类  
  58.         new Tester("mapped write"){  
  59.             public void test() throws IOException{  
  60.                 //利用RandomAccessFile初始化文件获取通道  
  61.                 FileChannel fc=new RandomAccessFile("baolei.txt","rw").getChannel();  
  62.                 //利用IntBuffer基本类型视图缓冲器来修改底层的ByteBuffer,实际上ByteBuffer是将数据移进移出通道的唯一方式  
  63.                 IntBuffer ib=fc.map(FileChannel.MapMode.READ_WRITE, 0,fc.size()).asIntBuffer();  
  64.                 for(int i=0;i<NUMOFINT;i++){  
  65.                     ib.put(i);  
  66.                 }  
  67.                   
  68.                 fc.close();  
  69.             }  
  70.         },  
  71.           
  72.         //下面的两个测试方法是测试read文件时的速度,基本和上面的两个一样  
  73.         new Tester("stream read"){  
  74.             public void test()throws IOException{  
  75.                 DataInputStream dis=new DataInputStream(new BufferedInputStream(new FileInputStream("baolei.txt")));  
  76.                   
  77.                 for(int i=0;i<NUMOFOUT;i++){  
  78.                     dis.readInt();  
  79.                 }  
  80.                 dis.close();  
  81.             }  
  82.         },  
  83.         new Tester("mapped read"){  
  84.             public void test() throws IOException{  
  85.                 FileChannel fc=new RandomAccessFile("baolei.txt","rw").getChannel();  
  86.                 IntBuffer ib=fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size()).asIntBuffer();  
  87.                 while(ib.hasRemaining()){  
  88.                     ib.get();  
  89.                 }  
  90.                   
  91.                 fc.close();  
  92.             }  
  93.         }  
  94.   
  95.     };  
  96.       
  97.     public static void main(String[] args){  
  98.         for(Tester test:tests){  
  99.             test.runTest();  
  100.         }  
  101.     }  
  102.   
  103. }  

 

   可以看到运行后的结果如下:

           使用stream write所消耗的时间:
           0.92
          使用mapped write所消耗的时间:
           0.12 
          使用stream read所消耗的时间:
           0.50
         使用mapped read所消耗的时间:
           0.06
    效率确实大幅度提高啊。

分享到:
评论

相关推荐

    MemMapComm:代码存储库,用于使用Java的内存映射文件测试IPC

    **在Java中使用内存映射文件进行IPC:** 1. **打开文件通道**:首先需要通过`FileChannel`类的静态方法`open()`或者`new FileInputStream().getChannel()`等方法获取文件通道。 2. **映射文件**:使用`FileChannel....

    java对大数据量文件内容的多线程读取和排序.pdf

    - 考虑使用内存映射文件(`MappedByteBuffer`)来提高读取效率,尤其是在操作系统支持大文件的情况下。 - 如果内存允许,可以采用Bloom Filter或布隆过滤器来减少排序过程中不必要的比较,降低CPU使用。 - 使用...

    Java文件操作源码大全

    19. **内存映射文件**:`java.nio.MappedByteBuffer`提供内存映射文件功能,提升大文件处理效率。 以上只是Java文件操作的一部分知识点,实际开发中还会涉及文件权限控制、并发访问、流操作等更多内容。了解并熟练...

    java版二级文件系统

    9. 性能优化:通过缓存技术提高文件操作的速度,例如使用内存缓存频繁访问的文件或目录项。 10. 错误处理:良好的文件系统应该能够处理各种异常情况,如磁盘满、文件不存在、IO错误等。 在进行课程设计时,学生...

    Java8新特性&Shiro&NIO&Redis分享

    - **内存映射文件**:可以直接将文件映射到内存中进行操作,提高读写性能。 - **分散/聚合读取**:可以在单次操作中将数据从一个Channel分散到多个Buffers,或将数据从多个Buffers聚集到一个Channel。 ### Redis #...

    nio-study:尼奥研究

    5. **内存映射文件(Memory-Mapped Files)**:NIO支持将文件直接映射到内存,使得读写操作如同访问数组一样快速高效。 在"nio-study-main"中,可能包含以下内容: - **示例代码**:展示了如何创建和使用通道、...

    bank银行转账存钱+txt

    - **内存映射文件**:使用`java.nio`包的`MappedByteBuffer`,可以将文件内容映射到内存,提高读写效率。 - **数据库替代**:在实际应用中,为了数据安全和性能,通常会使用关系型数据库(如MySQL)或NoSQL数据库...

    java上传组件

    另外,使用内存映射文件(Memory-Mapped Files)或者NIO(New IO)框架可以进一步提升文件处理速度。 10. **存储策略**: 上传的文件可能需要存储在不同的位置,如本地文件系统、云存储服务(如Amazon S3或阿里云...

    jspmusicupload_java_streamzdd_

    为了提高效率,文件通常不会直接存储在内存中,而是写入到磁盘。 6. **文件操作**: 使用`java.nio.file`包中的类,如`Files`和`Paths`,可以方便地进行文件读写和管理。例如,`Files.copy()`方法可用于将上传的`...

    java 细节代码收集 供自己查看

    如果文件较大,可能需要使用`FileChannel`和内存映射文件(MappedByteBuffer)来提高性能。 对于源码分析,Java的反射API允许在运行时检查类、接口、字段和方法的信息,甚至动态调用方法。这对于工具开发、插件系统...

    java版飞鸽传书源码

    此外,可能还使用了FileChannel和MappedByteBuffer进行内存映射文件操作,以提高文件读写效率。 5. **用户界面**:JavaFX或Swing库可能被用来构建图形用户界面,让用户能够直观地选择文件、查看传输进度和管理连接...

    数据导入导出 (java)

    可以使用数据库连接池(如HikariCP、C3P0)来优化数据库访问性能,同时,使用多线程处理大文件可提高效率。另外,错误处理和日志记录也是确保数据完整性和系统稳定性的关键。 5. **文件操作**: Java的`java.io`和...

    java断点续传的原理

    在Java中,可以使用`java.nio`包中的`FileChannel`和`MappedByteBuffer`来处理文件分块和内存映射,`HttpURLConnection`或`HttpClient`处理HTTP请求,以及`ExecutorService`来管理多线程。 9. **源码分析**: ...

    JDK6的13个新特性

    6. **泛型注解**:JDK6允许在泛型声明中使用注解,这对于编写元编程或验证工具非常有用。 7. **JSR 203 (NIO.2)**:也称为“New I/O”或“NIO 2”,提供了更好的文件I/O操作,包括异步I/O、路径API、文件属性查询...

    jdk-7u79-windows-x64

    - **字符串in switch语句(Strings in Switch)**:可以直接在switch语句中使用字符串,增强了语法的灵活性。 - **改进的文件I/O API(NIO.2)**:引入了新的`java.nio.file`包,提供了更强大的文件系统操作能力,...

    java jdk1.6 新特性 jaxb2 demo

    Java NIO(New I/O)在1.6版本中引入了NIO.2,提供了更高级别的文件系统操作API,如异步I/O、文件通道、文件属性和文件遍历等,增强了Java对非阻塞I/O的支持。 5. **Scripting API**: JSR 223引入了脚本引擎接口...

    jdk-7u80-windows-x64安装包

    JDK 1.7还提供了诸如`javadoc`(生成API文档)、`jmap`(内存映射工具)和`jconsole`(监控Java应用程序)等丰富的开发和诊断工具。 总结来说,JDK 1.7作为Java编程的重要组成部分,为开发者提供了强大的开发环境和...

Global site tag (gtag.js) - Google Analytics