您的位置:首页 > 编程语言 > Java开发

java_croe 学习笔记之新IO---java.nio 之内存映射文件

2009-12-19 10:02 1011 查看
发布日期: 2009-8-25 23:37:54 作者: 摘自来源: JavaEye博客

http://12616383.javaeye.com/blog/457582

参考:

无格式输入流 110秒

缓冲输入流 9.9秒

随机存取文件 162秒

内存映射文件 7.2秒

例子

Java代码



package twelve;

import java.io.BufferedInputStream;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStream;

import java.io.RandomAccessFile;

import java.nio.MappedByteBuffer;

import java.nio.channels.FileChannel;

import java.util.zip.CRC32;

/**

@Title NIOTTest.java

@description TODO

@author qinpeng

@date Aug 25, 2009 10:23:26 PM

*/

public class NIOTTest {

public static void main(String[] args) {

String fileName = "d://IOTest.pdf";

System.out.println("inputStream");

long start = System.currentTimeMillis();

long crcValue = checksumInputStreanm(fileName);

long end = System.currentTimeMillis();

System.out.println(Long.toHexString(crcValue));

System.out.println((end - start)+"耗时");

System.out.println("BufferedinputStream");

start = System.currentTimeMillis();

crcValue = checksumInputStreanm(fileName);

end = System.currentTimeMillis();

System.out.println(Long.toHexString(crcValue));

System.out.println((end - start)+"耗时");

System.out.println("RandomAccessFileinputStream");

start = System.currentTimeMillis();

crcValue = checksumInputStreanm(fileName);

end = System.currentTimeMillis();

System.out.println(Long.toHexString(crcValue));

System.out.println((end - start)+"耗时");

System.out.println(" MappedFile inputStream");

start = System.currentTimeMillis();

crcValue = checksumInputStreanm(fileName);

end = System.currentTimeMillis();

System.out.println(Long.toHexString(crcValue));

System.out.println((end - start)+"耗时");

}

public static long checksumInputStreanm(String fileName){

CRC32 crc = new CRC32();

try {

InputStream in = new FileInputStream(fileName);

int c;

while((c=in.read())!=-1){

crc.update(c);

}

} catch (FileNotFoundException e) {

e.printStackTrace();

System.err.print("NIOTTest--checksumInputStreanm--new FileInputStream is not found");

} catch(IOException ioe){

ioe.printStackTrace();

System.err.print("NIOTTest--checksumInputStreanm--new FileInputStream'read append IOException");

}

return crc.getValue();

}

public static long checksumBufferedInputStream(String fileName){

CRC32 crc = new CRC32();

try {

InputStream in = new BufferedInputStream(new FileInputStream(fileName));

int c;

while((c=in.read())!=-1){

crc.update(c);

}

} catch (FileNotFoundException e) {

e.printStackTrace();

System.err.print("NIOTTest--checksumBufferedInputStream--new FileInputStream is not found");

} catch(IOException ioe){

ioe.printStackTrace();

System.err.print("NIOTTest--checksumBufferedInputStream--new FileInputStream'read append IOException");

}

return crc.getValue();

}

public static long checksumRondomAccessFileInputStream(String fileName){

CRC32 crc = new CRC32();

try {

RandomAccessFile file = new RandomAccessFile(fileName,"r");

int c;

while((c=file.read())!=-1){

crc.update(c);

}

} catch (FileNotFoundException e) {

e.printStackTrace();

System.err.print("NIOTTest--checksumRondomAccessFileInputStream--new FileInputStream is not found");

} catch(IOException ioe){

ioe.printStackTrace();

System.err.print("NIOTTest--checksumRondomAccessFileInputStream--new FileInputStream'read append IOException");

}

return crc.getValue();

}

public static long checksumMappedFile(String fileName){

CRC32 crc = new CRC32();

try {

FileInputStream in = new FileInputStream(fileName);

FileChannel channel = in.getChannel();

int length = (int) channel.size();

MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, length);

for(int p = 0;p<length;p++){

int c = buffer.getInt(p);

crc.update(c);

}

} catch (FileNotFoundException e) {

e.printStackTrace();

System.err.print("NIOTTest--checksumRondomAccessFileInputStream--new FileInputStream is not found");

} catch(IOException ioe){

ioe.printStackTrace();

System.err.print("NIOTTest--checksumRondomAccessFileInputStream--new FileInputStream'read append IOException");

}

return crc.getValue();

}

}

------------------------------------------------】

有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问了。这种解决思路能大大简化修改文件的代码。下面就是一个简单的例子:

代码
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class LargeMappedFiles {
static int length = 0x8FFFFFF; // 128 Mb
public static void main(String[] args) throws Exception {
MappedByteBuffer out =
new RandomAccessFile("test.dat", "rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, length);
for(int i = 0; i < length; i++)
out.put((byte)'x');
System.out.println("Finished writing");
for(int i = length/2; i < length/2 + 6; i++)
System.out.print((char)out.get(i));
}
}
为了能以读写的方式打开文件,我们从RandomAccessFile入手。

拿到channel之后,我们用map( )方法生成了一个MappedByteBuffer。这是一种特殊的"direct buffer"。注意,你必须指明,它是从文件的哪个位置开始映射的,映射的范围又有多大;也就是说,它还可以映射一个大文件的某个小片断。

MappedByteBuffer是ByteBuffer的派生类,因此它具备了ByteBuffer的所有方法。这里只简单地演示了一下put( )和get( )方法,除此之外,你还可以使用asCharBuffer( )之类的方法。
上述例程创建了一个128MB的文件,或许这已经超出OS的允许范围了。文件的访问好像只是一瞬间的事,这是因为,真正调入内存的只是其中的一小部分,其余部分则被放在交换文件上。这样你就可以很方便地修改超大型的文件了(最大可以到2 GB)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐