内存映射文件是java NIO模块里非常有用的一个功能,它通过FileChannel中的map方法将文件片段映射到内存中,并且可以直接将对内存的操作反应到文件中,非常适合对大文件的操作,并且效率相比传统的字节IO流效率高出不少。

以下是我实现的一个简单的文件编辑器。

 1 /**
 2  * 文件编辑器
 3  * @author rui.chen
 4  *
 5  */
 6 public class MyFileEditor {
 7     private FileChannel channel;
 8     private RandomAccessFile file;
 9     
10     public MyFileEditor(String path){
11         try {
12             File f = new File(path);
13             if(!f.exists() || !f.isFile()){
14                 f.createNewFile();
15             }
16             file = new RandomAccessFile(f, "rw");
17         } catch (Exception e) {
18             e.printStackTrace();
19         }
20     }
21     
22     public void open(){
23         channel = file.getChannel();
24     }
25     
26     /**
27      * 在文件末尾添加内容
28      */
29     public void append(String content){
30         try {
31             override(content, (int) file.length());
32         } catch (IOException e) {
33             e.printStackTrace();
34         }
35     }
36     
37     /**
38      * 在position位置写入content,并覆盖原有内容
39      */
40     public void override(String content, int position){
41         try {
42             MappedByteBuffer buffer = channel.map(MapMode.READ_WRITE, position, content.length());
43             buffer.position(0);
44             buffer.put(content.getBytes());
45             buffer.flip();
46         } catch (IOException e) {
47             e.printStackTrace();
48         }
49     }
50     
51     /**
52      * 在position位置插入内容,不覆盖原有内容
53      */
54     public void insert(String content, int position){
55         try {
56             int length = (int) (file.length()-position+content.length());
57             int fileLen = (int) file.length();
58             MappedByteBuffer buffer = channel.map(MapMode.READ_WRITE, 
59                     position, length);
60             buffer.position(0);
61             byte[] dst = new byte[length];
62             byte[] contentBytes = content.getBytes();
63             for(int i=0; i<contentBytes.length; i++){
64                 dst[i] = contentBytes[i];
65             }
66             byte[] old = new byte[fileLen-position];
67             buffer.get(old, 0, fileLen-position);
68             buffer.position(0);
69             for(int i=0; i<old.length; i++){
70                 dst[i+contentBytes.length] = old[i];
71             }
72             buffer.put(dst);
73             buffer.flip();
74         } catch (IOException e) {
75             e.printStackTrace();
76         }
77     }
78     
79     public void close(){
80         if(channel.isOpen()){
81             try {
82                 channel.close();
83             } catch (IOException e) {
84                 e.printStackTrace();
85             }
86         }
87     }
88 }

通过下面的测试程序进行测试,文件大小为516MB,运行时间为44毫秒。

 1 public class NIOTest {
 2     public static void main(String[] args){
 3         MyFileEditor editor = new MyFileEditor("D:\\server.log.2013-05-02");
 4         editor.open();
 5         long start = System.currentTimeMillis();
 6         editor.append("content be appended");
 7         System.out.println("time cost: "+(System.currentTimeMillis()-start)+" milliseconds");
 8         editor.close();
 9     }
10 }

 

posted on 2013-05-17 10:12  壹零叁柒  阅读(222)  评论(0编辑  收藏  举报