在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如下为一个对比实验。
package com.jiubang;
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 com.jiubang;
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 Test2 {
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
e.printStackTrace();
} catch (IOException e) { // TODO
e.printStackTrace();
}
}
}
测试结果:
sum:0 time:1458
sum:0 time:67
sum:0 time:8
由此可见,将文件部分或者全部映射到内存后进行读写,速度将提高很多。
这是因为内存映射文件首先将外存上的文件映射到内存中的一块连续区域,被当成一个字节数组进行处理,读写操作直接对内存进行操作,而后再将内存区域重新映射到外存文件,这就节省了中间频繁的对外存进行读写的时间,大大降低了读写时间。
原文链接:
http://blog.csdn.net/tobacco5648/article/details/7679105
分享到:
相关推荐
下面的代码示例展示了如何使用内存映射文件处理大文件: ```java import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset....
Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...
6. **内存映射文件(Memory-Mapped Files)**: NIO允许将文件直接映射到内存,使得读写文件就像操作普通缓冲区一样快速。通过MappedByteBuffer类,可以直接在内存中对文件进行操作,提高大文件处理的性能。 7. **...
Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...
Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...
数字证书:从文件中读取数字证书,生成文件输入流,输入文件为c:/mycert.cer,获取一个处理X.509证书的证书工厂…… Java+ajax写的登录实例 1个目标文件 内容索引:Java源码,初学实例,ajax,登录 一个Java+ajax写的...
Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...
数字证书:从文件中读取数字证书,生成文件输入流,输入文件为c:/mycert.cer,获取一个处理X.509证书的证书工厂…… Java+ajax写的登录实例 1个目标文件 内容索引:Java源码,初学实例,ajax,登录 一个Java+ajax写的...
### Java NIO 系列教程知识点详解 ...此外,Java NIO 还提供了一系列辅助功能,如内存映射文件和文件锁定,进一步增强了其功能性和适用性。对于从事 Java 后端开发的工程师来说,熟练掌握 Java NIO 是十分必要的。
4. **内存映射文件**:NIO 支持将文件直接映射到内存中,这在处理大数据量时特别有用,因为它避免了多次数据复制。 #### 二、Java NIO 的核心组件 Java NIO 的核心组件主要包括 Channel 和 Buffer。 ##### 1. ...
再者,`集合框架`是Java中用于存储和操作对象的工具。它包括List(如ArrayList和LinkedList)、Set(如HashSet和TreeSet)、Map(如HashMap和TreeMap)等接口及其实现类。这些数据结构提供了丰富的操作方法,如添加...
4. **图片处理**:PDF中的图像需提取出来并保存为单独的图片文件,然后在HTML中用`<img>`标签引用。可能需要处理的问题包括图片格式转换(如PDF中的JPEG转为Web友好的PNG或JPEG)、大小调整和位置对应。 5. **CSS...
Xml配置文件在Struts和Hibernate中用于配置框架的工作方式,包括Action映射、数据源配置等。DaoClass是用于封装与数据库交互逻辑的组件,负责提供数据存取接口。ActionClass是Struts中的核心组件,用于处理用户请求...
H2 是一个开源的嵌入式数据库,支持多种模式:内存模式、文件模式及网络服务器模式。 - **SQLite**: 框架。SQLite 是一个无服务器的、零配置的、自包含的数据库引擎,非常适合嵌入到各种应用软件中。 - **MySQL**: ...
在IT行业中,XML(eXtensible Markup Language)是一种重要的数据交换格式,广泛应用于系统间的数据...在“mapxml”这个文件名中,我们可以推测这可能是一个与XML相关的映射文件,可能包含了键值对或其他结构化数据。
以上是对给定文件中的Java面试知识点进行了详细阐述,覆盖了线程管理、内存管理、垃圾回收以及I/O处理等多个方面。这些知识点对于准备Java面试的候选人来说至关重要,有助于深入理解Java语言的核心机制和技术细节。
- 集合框架是Java中用于存储、操作对象的重要工具,包括List、Set和Map接口,以及ArrayList、LinkedList、HashSet、HashMap等实现类。 - 泛型:Java 5引入泛型,增强了类型安全,允许在编译时检查类型。 4. **多...