1. 程式人生 > >Apache commons io 效率之嘗試與瞎寫

Apache commons io 效率之嘗試與瞎寫

         我們使用Apache commons io,主要是為了提升各種效率。比如開發的效率,讀取檔案的效率,輸出的效率等。輸入、輸入效率上的提升,是這個工具安身立命的本錢,是本;而開發效率的提升,能夠讓我們開發、專案相關人員獲取實在的效益,是葉。

         我們先說葉,再說本,對或者錯,都是我的一家之言,僅供參考。

●在input中,最值得關注的方法之一是AutoCloseInputStream

這個輸入流是一個底層輸入流的代理,它能夠在資料來源的內容被完全讀取到輸入流後,後者當用戶呼叫close()方法時,立即關閉底層的輸入流。釋放底層的資源(例如檔案的控制代碼)。這個類的好處就是避免我們在程式碼中忘記關閉底層的輸入流而造成檔案處於一直開啟的狀態。

我們知道對於某些檔案,只允許由一個程序開啟。如果我們使用後忘記關閉那麼該檔案將處於一直“開啟”的狀態,其它程序無法讀寫。例如下面的例子:

 InputStream ins = new FileInputStream(newFile("D:\\ffm83\\ffm83.txt"));
裡面的FileInputStream(FILE)在開啟後不能被顯式關閉,這將導致可能出現的問題。如果我們使用了AutoCloseInputStream,那麼當資料讀取完畢後,底層的輸入流會被自動關閉,迅速地釋放資源。
AutoCloseInputStream ins =newAutoCloseInputStream((new FileInputStream(newFile("D:\\ffm83\\ffm83.txt"))));

示例程式碼:

packagetest.ffm83.commons.io;

importjava.io.File;

importjava.io.FileInputStream;

importjava.io.FileWriter;

importjava.io.IOException;

importjava.io.Writer;

importorg.apache.commons.io.IOUtils;

importorg.apache.commons.io.input.AutoCloseInputStream;

importorg.apache.commons.lang.StringUtils;

/**

 * commonsio 的一些簡單基本用法

 * @author範芳銘

 */

public classIOAutoCloseUsage {

    publicstatic void main(String[] args) throws Exception {

        getInputCopyToWrite();

    }

    /**

     * 輸入流複製到輸出流,利用AutoCloseInputStream

     * @author 範芳銘

     */

    privatestatic void getInputCopyToWrite() throws

Exception {   

        AutoCloseInputStreamins =new AutoCloseInputStream((new FileInputStream(newFile("D:\\ffm83\\ffm83.txt"))));

        Writerwrite = new FileWriter("D:\\ffm83\\write.txt");

        try{

            IOUtils.copy(ins,write);

            System.out.println(StringUtils.center("輸入流複製到輸出流成功",50, "-"));

        }catch(IOException e){

            System.out.println(StringUtils.center("輸入流複製到輸出流失敗",50, "-"));

            e.printStackTrace();

        }  

        write.close();

        //ins.close(); 

    }

}

●在output中,最重要的方法是ByteArrayOutputStream,FileWriterWithEncoding,LockableFileWriter

ByteArrayOutputStream 方法提升了輸入輸出的效率;

FileWriterWithEncoding 提供了特殊功能簡化了效率;

LockableFileWriter 提供了特殊的功能;

為了檢視Apache提供的ByteArrayOutputStream是怎麼提供效率的,我們寫個程式來看看。為了讓測試有一定的客觀性,我們利用http://blog.csdn.net/ffm83/article/details/41848149部落格的頁面的原始碼,儲存到本地進行。這個頁面的原始碼儲存的檔案對應的就是D:\\ffm83\\ffmBlog.txt。

測試用程式碼如下:

packagetest.ffm83.commons.io;

importjava.io.ByteArrayOutputStream;

importjava.io.File;

importjava.io.FileInputStream;

importorg.apache.commons.io.input.AutoCloseInputStream;

importorg.apache.commons.lang.time.StopWatch;

/**

 * commons io 的ByteArrayOutputStream方法和java自帶的ByteArrayOutputStream效率比較。

 * @author 範芳銘

 */

publicclass ByteArrayOutputStreamTest {

         public final static int BUFFER_SIZE =4096;

         public static void main(String[] args)throws Exception {

                   runTestApacheMethod(100000,"熱身APACH方法");  //熱身下

                   runTestApacheMethod(500000,"執行APACHE方法"); //正式開跑

                   runTestJavaMethod(100000,"熱身JAVA自帶"); //熱身下

                   runTestJavaMethod(500000,"執行JAVA自帶"); //正式開跑

         }

         /**

          * 測試用的主執行方法

          * @author 範芳銘

          */

         private static voidrunTestJavaMethod(int iterations,String name) throws Exception{

                   StopWatch sw = newStopWatch();

                   sw.start();

                   for(int i = 0 ; i <iterations ;  i ++){

                            //在這裡呼叫需要執行的方法

                            runJavaByteArrayOutputStream();

                   }

                   sw.stop();

                   System.out.println(name +",累計花費的時間:" + sw.getTime() );

         }

         private static voidrunTestApacheMethod(int iterations,String name) throws Exception{

                   StopWatch sw = newStopWatch();

                   sw.start();

                   for(int i = 0 ; i <iterations ;  i ++){

                            //在這裡呼叫需要執行的方法

                            runApacheByteArrayOutputStream();

                   }

                   sw.stop();

                   System.out.println(name +",累計花費的時間:" + sw.getTime());

         }

         /**

          * 看java自帶的ByteArrayOutputStream效率

          * @author 範芳銘

          */

         private static voidrunJavaByteArrayOutputStream() throws Exception {      

                   AutoCloseInputStream ins =newAutoCloseInputStream((new FileInputStream(

                                     newFile("D:\\ffm83\\ffmBlog.txt"))));

                   ByteArrayOutputStreambouts=new ByteArrayOutputStream();

                   byte[] data = newbyte[BUFFER_SIZE];

                   int count = -1;

                   while((count =ins.read(data,0,BUFFER_SIZE)) != -1)

                             bouts.write(data, 0, count);

                   bouts.close();      

         }

         /**

          * 看java自帶的ByteArrayOutputStream效率

          * @author 範芳銘

          */

         private static voidrunApacheByteArrayOutputStream() throws Exception { 

                   AutoCloseInputStream ins =newAutoCloseInputStream((new FileInputStream(

                                     newFile("D:\\ffm83\\ffm83.txt"))));

                   org.apache.commons.io.output.ByteArrayOutputStreambouts =

                                     neworg.apache.commons.io.output.ByteArrayOutputStream();

                   byte[] data = newbyte[BUFFER_SIZE];

                   int count = -1;

                   while((count = ins.read(data,0,BUFFER_SIZE))!= -1)

                             bouts.write(data, 0, count);

                   bouts.close();      

         }

}

執行結果如下:

熱身APACH方法,累計花費的時間:9184

執行APACHE方法,累計花費的時間:43893

熱身JAVA自帶,累計花費的時間:17144

執行JAVA自帶,累計花費的時間:85052

時間效率提升不到50%,難道我眼鏡戴錯了嗎?

不過蚊子腿再細也是肉,雖然提升不多,好歹也是進步。換個思路再試試吧。

    /**

     * 看java自帶的ByteArrayOutputStream效率

     * @author 範芳銘

     */

    privatestatic void runJavaByteArrayOutputStream() throwsException {  

        AutoCloseInputStreamins =new AutoCloseInputStream((new FileInputStream(

                newFile("D:\\ffm83\\ffmBlog.txt"))));

        ByteArrayOutputStreambouts=new ByteArrayOutputStream();

        byte[]data = new byte[BUFFER_SIZE];

        intcount = -1;

        while((count= ins.read(data,0,BUFFER_SIZE)) != -1)

             bouts.write(data, 0, count);

        bouts.close(); 

    }

這程式碼裡有幾個主要方法,一個是AutoCloseInputStream讀取流檔案,然後才是ByteArrayOutputStream,不知道是否是兩個互相有影響,那麼把這個方法移開試試看吧。

調整後的程式碼如下:

package test.ffm83.commons.io;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileInputStream;

importorg.apache.commons.io.input.AutoCloseInputStream;

import org.apache.commons.lang.time.StopWatch;

/**

 * commonsio 的ByteArrayOutputStream方法和java自帶的ByteArrayOutputStream效率比較。

 * @author範芳銘

 */

public class ByteArrayOutputStreamTest {

    publicfinal static int BUFFER_SIZE = 4096;

    publicstatic void main(String[] args) throws Exception {

        AutoCloseInputStreamins =new AutoCloseInputStream((new FileInputStream(

                newFile("D:\\ffm83\\ffmBlog.txt"))));

        runTestApacheMethod(100000,"熱身APACH方法",ins);  //熱身下

        runTestApacheMethod(500000,"執行APACHE方法",ins);//正式開跑

        runTestJavaMethod(100000,"熱身JAVA自帶",ins);//熱身下

        runTestJavaMethod(500000,"執行JAVA自帶",ins);//正式開跑

    }

    /**

     * 測試用的主執行方法

     * @author 範芳銘

     */

    privatestatic void runTestJavaMethod(int iterations,String name,

            AutoCloseInputStreamins) throws Exception{

        StopWatchsw = new StopWatch();

        sw.start();

        for(inti = 0 ; i < iterations ;  i ++){

            //在這裡呼叫需要執行的方法

            runJavaByteArrayOutputStream(ins);

        }

        sw.stop();

        System.out.println(name+ ",累計花費的時間:" + sw.getTime() );

    }

    privatestatic void runTestApacheMethod(int iterations,String name,

            AutoCloseInputStreamins) throws Exception{

        StopWatchsw = new StopWatch();

        sw.start();

        for(inti = 0 ; i < iterations ;  i ++){

            //在這裡呼叫需要執行的方法

            runApacheByteArrayOutputStream(ins);

        }

        sw.stop();

        System.out.println(name+ ",累計花費的時間:" + sw.getTime());

    }

    /**

     * 看java自帶的ByteArrayOutputStream效率

     * @author 範芳銘

     */

    privatestatic void runJavaByteArrayOutputStream(AutoCloseInputStream ins) throwsException {  

        ByteArrayOutputStreambouts=new ByteArrayOutputStream();

        byte[]data = new byte[BUFFER_SIZE];

        intcount = -1;

        while((count= ins.read(data,0,BUFFER_SIZE)) != -1)

             bouts.write(data, 0, count);

        bouts.close(); 

    }

        /**

     * 看apache的ByteArrayOutputStream效率

     * @author 範芳銘

     */ privatestatic void runApacheByteArrayOutputStream(AutoCloseInputStream ins) throwsException {

        org.apache.commons.io.output.ByteArrayOutputStreambouts =

                neworg.apache.commons.io.output.ByteArrayOutputStream();

        byte[]data = new byte[BUFFER_SIZE];

        intcount = -1;

        while((count= ins.read(data,0,BUFFER_SIZE)) != -1)

             bouts.write(data, 0, count);

        //bouts.write(ins);

        bouts.close(); 

    }

}

執行結果如下:

熱身APACH方法,累計花費的時間:128

執行APACHE方法,累計花費的時間:530

熱身JAVA自帶,累計花費的時間:85

執行JAVA自帶,累計花費的時間:434

這個,這個出人意料,apache commons 的方法居然比java原生態的居然要慢50%。檢視apachecommons io中關於ByteArrayOutputStream的部分,相比於JDK自帶的方法,這個類多了一個write(InputStream in)的方法。

把這段程式碼調整下:

    privatestatic void runApacheByteArrayOutputStream(AutoCloseInputStreamins) throws Exception {

        org.apache.commons.io.output.ByteArrayOutputStreambouts =

                neworg.apache.commons.io.output.ByteArrayOutputStream();

/*      byte[]data = new byte[BUFFER_SIZE];

        intcount = -1;

        while((count= ins.read(data,0,BUFFER_SIZE)) != -1)

             bouts.write(data, 0, count); */

        bouts.write(ins);

        bouts.close(); 

    }

執行結果如下:

熱身APACH方法,累計花費的時間:43

執行APACHE方法,累計花費的時間:146

熱身JAVA自帶,累計花費的時間:82

執行JAVA自帶,累計花費的時間:354

這一次,apache commons 的方法比java原生態的居然要快50%以上。使用新的類,那麼就要儘量用它配套的方法,否則有可能得到錯誤甚至相反的結果。

我們這個應用,用到的方法很少,因此可以進一步研究:

() 
          Creates a new byte array output stream.

(int size) 
          Creates a new byte array output stream, with a buffer capacity of the specified size, in bytes.

有一個是有引數的,一個是沒有引數的,我們剛才測試用的是沒有引數的。我們在各種buff中可能有了解,如果把buff的值擴大,一般效率會提升的,試驗是檢驗真理的最高標準,我們動手試一下。

程式碼做一下調整:

    /**

     * 看apache的ByteArrayOutputStream效率

     * @author 範芳銘

     */

    privatestatic void runApacheByteArrayOutputStream(AutoCloseInputStreamins) throws Exception {

        org.apache.commons.io.output.ByteArrayOutputStreambouts =

                neworg.apache.commons.io.output.ByteArrayOutputStream(40960);

/*      byte[]data = new byte[BUFFER_SIZE];

        intcount = -1;

        while((count= ins.read(data,0,BUFFER_SIZE)) != -1)

             bouts.write(data, 0, count); */

        bouts.write(ins);

        bouts.close(); 

    }

執行結果如下:

熱身APACH方法,size40960,累計花費的時間:668

執行APACHE方法,size40960,累計花費的時間:3702

熱身JAVA自帶,累計花費的時間:74

執行JAVA自帶,累計花費的時間:379

程式碼繼續調整下:

    /**

     * 看apache的ByteArrayOutputStream效率

     * @author 範芳銘

     */

    privatestatic void runApacheByteArrayOutputStream(AutoCloseInputStream ins)throws Exception {

        org.apache.commons.io.output.ByteArrayOutputStreambouts =

                neworg.apache.commons.io.output.ByteArrayOutputStream(4);

/*      byte[]data = new byte[BUFFER_SIZE];

        intcount = -1;

        while((count= ins.read(data,0,BUFFER_SIZE)) != -1)

             bouts.write(data, 0, count); */

        bouts.write(ins);

        bouts.close(); 

    }

執行結果如下:

熱身APACH方法,size4,累計花費的時間:22

執行APACHE方法,size4,累計花費的時間:73

熱身JAVA自帶,累計花費的時間:79

執行JAVA自帶,累計花費的時間:355

嘗試了這麼多,總結一下:

l   使用新的類,那麼就要儘量用它配套的方法,否則有可能得到錯誤甚至相反的結果;

l   引數不要去想當然,要根據實際情況去調整,如果對效率有特殊要求,必要的測試是不可缺少的;

FileWriterWithEncoding
從這個類的名稱已經可以很清楚的知道它的作用了。在JDK自帶的FileWriter中,是無法設定encoding的,這個類允許我們採用預設或者指定的encoding,以字元的形式寫到檔案。為什麼這個類可以改變字元嗯?
原理很簡單:無非使用了OutputStreamWriter。而且這個類並不是繼承與FileWriter,而是直接繼承於Writer。

●LockableFileWriter
用“檔案鎖”而非“物件鎖”來限制多執行緒環境下的寫動作。這個類採用在JDK預設的系統臨時目錄下寫檔案:java.io.tmpdir屬性。而且允許我們設定encoding。

如果多執行緒需要讀寫同一個檔案,那麼可以通過本方法對檔案進行加鎖操作。

相關推薦

Apache commons io 效率嘗試

         我們使用Apache commons io,主要是為了提升各種效率。比如開發的效率,讀取檔案的效率,輸出的效率等。輸入、輸入效率上的提升,是這個工具安身立命的本錢,是本;而開發效率的提升,能夠讓我們開發、專案相關人員獲取實在的效益,是葉。         

Apache Commons IOFileUtils的常用方法

unit 文件系統 全部 string類 force 輸出 cfi 異常 兩個文件 Apache Commons IO 在學習io流的時候研究(翻譯)了一下這個,只有FileUtils的某些方法,並不全面,還請諒解 org.apache.commons.io 這個包下定義了

使用Apache Commons IO組件讀取大文件

utils apache 普通 out right ack close 一次 solid Apache Commons IO讀取文件代碼如下: Files.readLines(new File(path), Charsets.UTF_8); FileUtils.readLi

常用操作提高效率 for in

問題如何而來:    對於剛參加工作的我  批量刪除資料通常採用的是前端傳遞到後臺一個物件的id字串  通過逗號分隔的多個id  或者收的直接是一個id陣列 兩個原理一樣第一個後臺要在次使用split(",")做分隔成陣列 ,然後通過遍歷陣列  採

org.apache.commons.io包中的FileUtils檔案工具類詳細介紹

FileUtils類的應用 寫入一個檔案; 從檔案中讀取; 建立一個資料夾,包括資料夾; 複製檔案和資料夾; 刪除檔案和資料夾; 從URL地址中獲取檔案; 通過檔案過濾器和副檔名列出檔案和資料夾; 比較檔案內容; 檔案最後的修改時間;

org.apache.commons.io jar的使用(二)FileUtils

FileUtils 是檔案操作工具類 使用方法示例: import org.apache.commons.io.FileUtils; import org.apache.commons.io.LineIterator; import org.apache.commons.

Apache-commons-io包的使用及常用方法

      首先,我們要下載FileUtils相關的Apache-commons-io jar包以及api文件。FileUtils類庫的下載頁面在:       http://commons.apache.org/proper/com

codingdict.com -Apache Commons IO教程

Apache Commons IO概述 Apache Commons IO環境設定 Apache Commons IO IOUtils Apache Commons IO FileUtils Apac

使用org apache commons io FileUtils IOUtils 工具類操作檔案

                File src = new File("G:/2012/portal/login.jsp");File tar = new File("G:/2012/portal/loginZs.jsp");File tarDir = new File("G:/2012/portal/ce

org.apache.commons.io如何使用

FileUtils類的應用 1、寫入一個檔案; 2、從檔案中讀取; 3、建立一個資料夾,包括資料夾; 4、複製檔案和資料夾; 5、刪除檔案和資料夾; 6、從URL地址中獲取檔案; 7、通過檔案過濾器和副檔名列出檔案和資料夾; 8、比較檔案內容; 9、檔案最後

使用org.apache.commons.io.FileUtils,IOUtils;工具類操作檔案

Commons IO是apache的一個開源的工具包,封裝了IO操作的相關類,使用Commons IO可以很方便的讀寫檔案, FileUtils 中提供了許多設計檔案操作的 已封裝好的方法。 IOUtils 則是提供了讀寫檔案的方法。 File s

apache commons io 2.2(六)工具部分

近段時間,對apache commons io的原始碼做了深入的瞭解,在此把一些見解與大家分享。 首先我選擇了大部分框架還依賴的2.2版本而不是最新的2.4版本(2.5發行版還沒有釋出)進行原始碼的研讀,今天就簡介一下commons io的工具部分。 複製工具類: or

Java ioFileOutputStreamFileInputStream 詳解

FileOutputStream 檔案輸出流 方法程式碼詳解: public class Demo01 { public static void main(String[] a

linux系統執行java專案報錯Caused by: java.lang.NoSuchMethodError: org.apache.commons.io.IOUtils.closeQuietly

Caused by: java.lang.NoSuchMethodError: org.apache.commons.io.IOUtils.closeQuietly(Ljava/io/Closeable;)Vat org.apache.commons.io.FileUtil

org.apache.commons.io.FileUtils 檔案處理相關

import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Properties; /** * 字串工具箱 * * @author leizhimin 2008-12-15 22:40:12

Java (三)APACHE Commons IO 常規炒

.project lis -i 以及 rec project import ngs clip 例1:查看文件、文件夾的長度(大小)。 1 import java.io.File; 2 3 import org.apache.commons.io.FileU

python pandas IO tools read_csv檔案讀引數詳解

python pandas IO tools 之csv檔案讀寫 讀取csv檔案:pd.read_csv(),寫入csv檔案:pd.to_csv() pandas還可以讀取一下檔案: read_csv, read_excel, read_hdf,

前端進階認識compose方法

![](https://imgkr2.cn-bj.ufileos.com/b7e1c8ed-39e6-4260-b4f8-87b1941c7403.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=jJuX

Java-IO轉換流的使用和編碼解碼原理

鍵盤輸入 tostring delet 特點 rgb utf8 equals pri 數據 一、理論: 1、字符流和字節流區別是什麽? 字符流=字節流+編碼集,在實際讀取的時候其實字符流還是按照字節來讀取,但是會更具編碼集進行查找編碼集字典解析相應的字節,使得一次讀取出一個

Java——Properties集合,Object序列化流反序列化流,打印流,commons-IO文件工具類

都是 oos times odi store buffer src object 所有 一、properties集合 集合對象Properties類,繼承Hashtable,實現Map接口,可以和IO對象結合使用,實現數據的持久存儲。 p { margin-bottom: