发布日期: 2009-8-25 23:37:54 作者: 摘自来源: JavaEye博客
http://12616383.javaeye.com/blog/457582
参考:
无格式输入流 110秒
缓冲输入流 9.9秒
随机存取文件 162秒
内存映射文件 7.2秒
例子
- 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)。