国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java中使用內存映射實現大文件上傳實例

2019-11-26 15:19:23
字體:
來源:轉載
供稿:網友

在處理大文件時,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 來進行頻繁的讀寫操作,都將導致進程因頻繁讀寫外存而降低速度.如下為一個對比實驗。

復制代碼 代碼如下:

package test; 

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 test; 

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(); 
        } 

    } 

}


測試結果:
復制代碼 代碼如下:

sum:0 time:1458 
sum:0 time:67 
sum:0 time:8

由此可見,將文件部分或者全部映射到內存后進行讀寫,速度將提高很多。

這是因為內存映射文件首先將外存上的文件映射到內存中的一塊連續區域,被當成一個字節數組進行處理,讀寫操作直接對內存進行操作,而后再將內存區域重新映射到外存文件,這就節省了中間頻繁的對外存進行讀寫的時間,大大降低了讀寫時間。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 乐都县| 邵阳县| 阿城市| 桂东县| 翁牛特旗| 于都县| 济源市| 磐石市| 茂名市| 图片| 寻乌县| 册亨县| 绍兴县| 滨海县| 凤冈县| 萍乡市| 繁峙县| 吉林省| 绥化市| 奇台县| 中山市| 绥芬河市| 和龙市| 南城县| 万荣县| 慈溪市| 绥滨县| 孟津县| 常宁市| 沅江市| 清新县| 乡城县| 邵阳市| 文成县| 赞皇县| 秭归县| 当涂县| 玛纳斯县| 齐齐哈尔市| 龙南县| 常德市|