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)。
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)。
相关文章推荐
- [Java][IO]JAVA NIO之浅谈内存映射文件原理与DirectMemory
- [Java][IO]JAVA NIO之浅谈内存映射文件原理与DirectMemory
- Java NIO笔记之内存映射文件
- Java IO学习笔记(五):内存操作流
- 黑马程序员_O‘Reilly java nio学习笔记之通道_内存映射文件&&Channel-to-Channel 传输
- 【JavaNIO的深入研究4】内存映射文件I/O,大文件读写操作,Java nio之MappedByteBuffer,高效文件/内存映射
- 【Java学习笔记】18.Java 流(Stream)、文件(File)和IO
- Java学习笔记(十三)——通过Netbeans开发环境生成oracle数据库中表的对应hibernate映射文件
- Java学习笔记——File类文件管理及IO读写、复制操作
- NIO--JAVA NIO之浅谈内存映射文件原理与DirectMemory
- Java-NIO(五):通道(Channel)的数据传输与内存映射文件
- Java IO 实现文件复制 -Java 学习笔记 (25)
- Java IO ---学习笔记(标准流、内存读写流、顺序输入流)
- [原创]java WEB学习笔记81:Hibernate学习之路--- 对象关系映射文件(.hbm.xml):hibernate-mapping 节点,class节点,id节点(主键生成策略),property节点,在hibernate 中 java类型 与sql类型之间的对应关系,Java 时间和日期类型的映射,Java 大对象类型 的 映射 (了解),映射组成关系
- JAVA NIO之浅谈内存映射文件原理与DirectMemory
- java io文件学习笔记
- JAVA NIO FileChannel 内存映射文件
- 【JavaNIO的深入研究4】内存映射文件I/O,大文件读写操作,Java nio之MappedByteBuffer,高效文件/内存映射
- java学习笔记 IO学习笔记1 文件
- java NIO非阻塞式IO网络编程学习笔记(一)