常見的幾種文件讀到字節數組中的速度對比

網上了一些大神對文件讀到數組中的總結,自己對幾種方式做了個簡單的測試,分享一下,其實就是時間與內存空間之間的轉換,用的時候還需根據需求來選擇。

每次7個文件,循環50次

package com.sztaiji.utils;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;

public class FileUtils {
    
    public static byte[] getContent(String filePath) throws IOException {
        File file = new File(filePath);
        long fileSize = file.length();
        if (fileSize > Integer.MAX_VALUE) {
            System.out.println("file too big...");
            return null;
        }
        FileInputStream fi = new FileInputStream(file);
        byte[] buffer = new byte[(int) fileSize];
        int offset = 0;
        int numRead = 0;
        while (offset < buffer.length && (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) {
            offset += numRead;
        }
        // 確保所有數據均被讀取
        if (offset != buffer.length) {
            throw new IOException("Could not completely read file " + file.getName());
        }
        fi.close();
        return buffer;
    }

    /**
     * the traditional io way
     * 
     * @param filename
     * @return
     * @throws IOException
     */
    public static byte[] toByteArray(String filename) throws IOException {

        File f = new File(filename);
        if (!f.exists()) {
            throw new FileNotFoundException(filename);
        }

        ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
        BufferedInputStream in = null;
        try {
            in = new BufferedInputStream(new FileInputStream(f));
            int buf_size = 1024;
            byte[] buffer = new byte[buf_size];
            int len = 0;
            while (-1 != (len = in.read(buffer, 0, buf_size))) {
                bos.write(buffer, 0, len);
            }
            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            bos.close();
        }
    }

    /**
     * NIO way
     * 個人比較推薦
     * @param filename
     * @return
     * @throws IOException
     */
    public static byte[] toByteArray2(String filename) throws IOException {

        File f = new File(filename);
        if (!f.exists()) {
            throw new FileNotFoundException(filename);
        }

        FileChannel channel = null;
        FileInputStream fs = null;
        try {
            fs = new FileInputStream(f);
            channel = fs.getChannel();
            ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
            while ((channel.read(byteBuffer)) > 0) {
                // do nothing
                // System.out.println("reading");
            }
            return byteBuffer.array();
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                channel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                fs.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @param filename
     * @return
     * @throws IOException
     */
    public static byte[] toByteArray3(String filename) throws IOException {

        FileChannel fc = null;
        try {
            fc = new RandomAccessFile(filename, "r").getChannel();
            MappedByteBuffer byteBuffer = fc.map(MapMode.READ_ONLY, 0, fc.size()).load();
            //System.out.println(byteBuffer.isLoaded());
            byte[] result = new byte[(int) fc.size()];
            if (byteBuffer.remaining() > 0) {
                // System.out.println("remain");
                byteBuffer.get(result, 0, byteBuffer.remaining());
            }
            return result;
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                fc.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
 

//測試類

package com.sztaiji.rsa;

import java.io.IOException;

import org.junit.Test;

import com.sztaiji.utils.FileUtils;

public class FileUtilsTest {
    String filePath = "F:/testFile/quartz.sql";
    String filePathPdf = "F:/testFile/Thymeleaf使用手冊.pdf";
    String filePathDocx = "F:/testFile/權責清單關係表.docx";
    String filePathXlsx = "F:/testFile/資源開通明細0930.xlsx";
    String filePathMP3 = "F:/testFile/花橋流水.mp3";
    String filePathMp4 = "F:/testFile/ureka_Client.mp4";
    String filePathZip = "F:/testFile/apache-ant.zip";
    
    //大文件 1G+
    String filePathOrc = "E:/my_oracle/win64_11gR2_database_2of2.zip";
    
    
    String [] pathArr = new String[]{filePath,filePathPdf,filePathDocx,filePathXlsx,filePathMP3,filePathMp4,filePathZip,filePathOrc};
    int cunt = 50; //循環次數
    
    @Test
    public void getContentTest() throws IOException{
        byte[] byt = null;
        long sumTime = 0;
        for (int i = 0; i < cunt; i++) {
            long start = System.currentTimeMillis();
            for (String path : pathArr) {
                byt = null;
                byt = FileUtils.getContent(path);
            }
            long end = System.currentTimeMillis();
            sumTime += (end-start);
            System.out.print((i+1) + "."+(end-start)+";");
            if((double)i%15 == 0){
                System.out.println();
            }
        }
        System.out.println();
        System.out.println("getContent -- 共耗時 :【"+sumTime+"】毫秒, 平均每次:【"+(sumTime/cunt)+"】毫秒");
//        1.92;2.91;3.92;4.89;5.82;6.86;7.87;8.92;9.88;10.86;11.87;12.85;13.88;14.84;15.83;16.84;
//        17.85;18.91;19.86;20.83;21.81;22.84;23.82;24.82;25.86;26.84;27.88;28.85;29.90;30.87;31.90;
//        32.86;33.86;34.82;35.92;36.84;37.88;38.329;39.92;40.102;41.92;42.91;43.87;44.83;45.82;46.86;
//        47.83;48.86;49.85;50.84;
//        getContent -- 共耗時 :【4580】毫秒, 平均每次:【91】毫秒

//含大文件
//        1.1055;2.1080;3.1213;4.1043;5.1138;6.1048;7.1185;8.1058;9.1154;10.984;11.1071;12.996;13.1178;14.939;15.1115;16.773;
//        17.772;18.761;19.761;20.786;21.758;22.762;23.754;24.750;25.738;26.751;27.762;28.785;29.739;30.763;31.772;
//        32.742;33.795;34.738;35.748;36.764;37.755;38.753;39.756;40.734;41.773;42.750;43.738;44.758;45.749;46.742;
//        47.743;48.756;49.731;50.750;
//        getContent -- 共耗時 :【42719】毫秒, 平均每次:【854】毫秒
    }
    
    @Test
    public void getToByteArray() throws IOException{
        byte[] byt = null;
        long sumTime = 0;
        for (int i = 0; i < cunt; i++) {
            long start = System.currentTimeMillis();
            for (String path : pathArr) {
                byt = null;
                byt = FileUtils.toByteArray(path);
            }
            long end = System.currentTimeMillis();
            sumTime += (end-start);
            System.out.print((i+1) + "."+(end-start)+";");
            if((double)i%15 == 0){
                System.out.println();
            }
        }
        System.out.println();
        System.out.println("toByteArray -- 共耗時 :【"+sumTime+"】毫秒, 平均每次:【"+(sumTime/cunt)+"】毫秒");
        
//        1.149;2.140;3.122;4.123;5.124;6.121;7.128;8.120;9.130;10.119;11.121;12.124;13.121;14.158;15.113;16.128;
//        17.100;18.126;19.101;20.88;21.134;22.82;23.382;24.86;25.110;26.86;27.108;28.129;29.82;30.83;31.79;
//        32.100;33.78;34.77;35.76;36.122;37.117;38.83;39.80;40.81;41.83;42.118;43.84;44.81;45.81;46.82;
//        47.109;48.133;49.131;50.84;
//        toByteArray -- 共耗時 :【5617】毫秒, 平均每次:【112】毫秒

//含大文件
//        1.1349;2.1194;3.1216;4.1225;5.1188;6.1158;7.1172;8.1202;9.1171;10.1177;11.1176;12.1150;13.1127;14.1137;15.1150;16.1083;
//        17.1109;18.1230;19.1054;20.1007;21.994;22.983;23.970;24.996;25.962;26.972;27.955;28.985;29.957;30.969;31.953;
//        32.936;33.1004;34.1007;35.1025;36.1009;37.1038;38.977;39.969;40.998;41.1038;42.1027;43.1004;44.985;45.979;46.983;
//        47.1016;48.1032;49.1002;50.984;
//        toByteArray -- 共耗時 :【52984】毫秒, 平均每次:【1059】毫秒
    }
    
    @Test
    public void getToByteArray2() throws IOException{
        byte[] byt = null;
        long sumTime = 0;
        for (int i = 0; i < cunt; i++) {
            long start = System.currentTimeMillis();
            for (String path : pathArr) {
                byt = null;
                byt = FileUtils.toByteArray2(path);
            }
            long end = System.currentTimeMillis();
            sumTime += (end-start);
            System.out.print((i+1) + "."+(end-start)+";");
            if((double)i%15 == 0){
                System.out.println();
            }
        }
        System.out.println();
        System.out.println("toByteArray2 -- 共耗時 :【"+sumTime+"】毫秒, 平均每次:【"+(sumTime/cunt)+"】毫秒");
        
//        1.102;2.69;3.73;4.71;5.64;6.61;7.58;8.62;9.63;10.61;11.65;12.59;13.65;14.63;15.59;16.61;
//        17.58;18.62;19.60;20.67;21.63;22.61;23.62;24.55;25.60;26.60;27.64;28.59;29.60;30.59;31.63;
//        32.72;33.61;34.60;35.60;36.73;37.47;38.63;39.294;40.47;41.59;42.117;43.42;44.43;45.47;46.45;
//        47.39;48.41;49.40;50.41;
//        toByteArray2 -- 共耗時 :【3260】毫秒, 平均每次:【65】毫秒

//含大文件    
//        1.983;2.465;3.465;4.471;5.457;6.448;7.466;8.475;9.455;10.636;11.451;12.476;13.469;14.461;15.465;16.475;
//        17.457;18.460;19.456;20.459;21.492;22.452;23.453;24.455;25.455;26.456;27.460;28.458;29.474;30.465;31.459;
//        32.467;33.460;34.479;35.461;36.461;37.466;38.460;39.452;40.452;41.454;42.486;43.464;44.460;45.457;46.451;
//        47.473;48.460;49.456;50.464;
//        toByteArray2 -- 共耗時 :【23812】毫秒, 平均每次:【476】毫秒
    }
    
    @Test
    public void getToByteArray3() throws IOException{
        byte[] byt = null;
        long sumTime = 0;
        for (int i = 0; i < cunt; i++) {
            long start = System.currentTimeMillis();
            for (String path : pathArr) {
                byt = null;
                byt = FileUtils.toByteArray3(path);
            }
            long end = System.currentTimeMillis();
            sumTime += (end-start);
            System.out.print((i+1) + "."+(end-start)+";");
            if((double)i%15 == 0){
                System.out.println();
            }
        }
        System.out.println();
        System.out.println("toByteArray3 -- 共耗時 :【"+sumTime+"】毫秒, 平均每次:【"+(sumTime/cunt)+"】毫秒");
        
//        1.81;2.74;3.71;4.97;5.72;6.66;7.66;8.74;9.73;10.63;11.70;12.71;13.79;14.69;15.72;16.69;
//        17.74;18.74;19.67;20.68;21.70;22.79;23.66;24.66;25.67;26.73;27.72;28.67;29.67;30.72;31.73;
//        32.74;33.65;34.80;35.73;36.65;37.66;38.294;39.63;40.72;41.70;42.72;43.75;44.71;45.65;46.64;
//        47.67;48.67;49.70;50.67;
//        toByteArray3 -- 共耗時 :【3762】毫秒, 平均每次:【75】毫秒

//含大文件
//        1.925;2.843;3.1022;4.864;5.982;6.888;7.986;8.867;9.959;10.878;11.984;12.846;13.1004;14.763;15.863;16.585;
//        17.563;18.578;19.559;20.607;21.595;22.554;23.547;24.553;25.554;26.552;27.564;28.579;29.557;30.555;31.543;
//        32.581;33.553;34.554;35.551;36.546;37.548;38.562;39.576;40.560;41.548;42.550;43.564;44.555;45.550;46.587;
//        47.548;48.543;49.546;50.576;
//        toByteArray3 -- 共耗時 :【33317】毫秒, 平均每次:【666】毫秒
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章