<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 262,  comments - 221,  trackbacks - 0
    【一】Apache commons IO包之FileUtils

    IO文件操作,可以說是除了JDBC操作之外,日常最常用的功能之一了。IO的讀寫方式如何,直接影響到系統的性能。很多時候系統的性能瓶頸往往不是出現在對象層面,而是出現在底層的IO層面上。

    Apache commosn IO包在input, output包的基礎上,提供了一個高效,方便的文件類處理工具:FileUtils,其功能涵蓋了所有日常常用的IO操作,由于這個類的部分方法底層是基于Apache commons IO自己的讀寫流去實現的,所以在性能上會相對高于JDK自帶的類(具體原因可以參考這篇文章:IO與文件讀寫---使用Apache commons io包提高讀寫效率)

    根據Apache commons IO官方的說法,這個類可以提供如下功能:



    總體上來說,主要有:

     ※ 資源的創建、刪除
     ※ 資源的復制、移動
     ※ 資源的讀寫
     ※ 資源的比較
     ※ 資源的過濾
     ※ 資源的轉換

    【二】FileUtils的常用API及解析

    ①資源的創建、刪除

     ※ 目錄的創建: 
    forceMkdir(File directory),這個方法可以在父目錄不存在的情況下,連續創建多個目錄。但如果同名的目錄已經存在或者無權創建,則拋出異常

     ※ 文件的創建:
    touch(File file),這個方法用于創建一個size為0的文件,然后迅速關閉輸出流。如果文件已經存在則簡單地修改一下文件的modify time

     ※ 目錄/文件的刪除:
    void deleteDirectory(File directory),遞歸地刪除目錄及其下的所有內容。

    boolean deleteQuietly(File file),相比于JDK的delete()方法有兩個不同:首先它不需要被刪除目錄下的內容為空,其次它不會拋出任何IOException。

    void forceDelete(File file),強行刪除file對象,如果是目錄對象則遞歸刪除子目錄。如果刪除失敗則顯式地拋出IOException。

    void forceDeleteOnExit(File file),當JVM退出時,把file對象刪除。如果是目錄對象則遞歸刪除子目錄。


    ②資源的復制、移動

     ※ 復制目錄或文件
    copyDirectory(File srcDir, File destDir, FileFilter filter, boolean preserveFileDate),這個方法用于把源目錄及其下面的子目錄,文件一起拷貝到目標位置(名稱可改)。而且該方法允許在拷貝的過程中進行過濾,指定僅拷貝那些符合條件的資源。最后一個選項用來表明是否保留文件原有的創建、修改日期還是使用最新的日期。

    copyDirectoryToDirectory(File srcDir, File destDir),這個方法和上面的區別在于:首先上面的方法是拷貝到destDir的位置,而這個方法是拷貝到destDir“之下”的位置。其次上面的方法可以在拷貝的同時改名,這個方法不能,拷貝后仍然使用原來的名稱。

    copyFile(File srcFile, File destFile, boolean preserveFileDate),類似于上面的copyDirectory方法。

    copyFileToDirectory(File srcFile, File destDir, boolean preserveFileDate),類似與上面的copyDirectoryToDirectory方法。

     ※ 移動目錄或文件
    moveToDirectory(File srcFile, File destDir, boolean createDestDir),這個方法用于移動一個文件或者目錄到指定位置。

    ③資源的讀寫

    這一部分是FileUtils的精華部分。

     ※ 讀入文件
    FileUtils支持對文件以字節數組,字符串,行的方式讀入。對應方法分別是:

    byte[] readFileToByteArray(File file) 
    String readFileToString(File file)
    String readFileToString(File file, String encoding)
    List readLines(File file)
    List readLines(File file, String encoding)


    這里我們關心的是對于大文件,FileUtils是如何讀入的?看看下面的源代碼:
    /**
         * Reads the contents of a file into a String.
         * The file is always closed.
         *
         * 
    @param file  the file to read, must not be <code>null</code>
         * 
    @param encoding  the encoding to use, <code>null</code> means platform default
         * 
    @return the file contents, never <code>null</code>
         * 
    @throws IOException in case of an I/O error
         * 
    @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
         
    */

        
    public static String readFileToString(File file, String encoding) throws IOException {
            InputStream in 
    = null;
            
    try {
                in 
    = openInputStream(file);
                
    return IOUtils.toString(in, encoding);
            }
     finally {
                IOUtils.closeQuietly(in);
            }

        }

    可以見到這個方法調用了IOUtils的toString方法,那么這個過程的底層細節是如何的呢?
    public static String toString(InputStream input, String encoding)
                
    throws IOException {
            StringWriter sw 
    = new StringWriter();
            copy(input, sw, encoding);
            
    return sw.toString();
        }


    public static void copy(InputStream input, Writer output, String encoding)
                
    throws IOException {
            
    if (encoding == null{
                copy(input, output);
            }
     else {
                InputStreamReader in = new InputStreamReader(input, encoding);
                copy(in, output);
            }

        }


    /**
         * Copy bytes from a large (over 2GB) <code>InputStream</code> to an
         * <code>OutputStream</code>.
         * <p>
         * This method buffers the input internally, so there is no need to use a
         * <code>BufferedInputStream</code>.
         * 
         * 
    @param input  the <code>InputStream</code> to read from
         * 
    @param output  the <code>OutputStream</code> to write to
         * 
    @return the number of bytes copied
         * 
    @throws NullPointerException if the input or output is null
         * 
    @throws IOException if an I/O error occurs
         * 
    @since Commons IO 1.3
         
    */

        
    public static long copyLarge(InputStream input, OutputStream output)
                
    throws IOException {
            
    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
            long count = 0;
            
    int n = 0;
            
    while (-1 != (= input.read(buffer))) {
                output.write(buffer, 
    0, n);
                count 
    += n;
            }

            
    return count;
        }

    可以看到,Apache commons IO的底層是采用InputStreamReader來讀的,而且是連續不斷地在內存中構造String對象,如果有一個2G文件,那么將會在內存中構造一個2G的String對象。

     ※ 寫入文件
    void writeLines(File file, String encoding, Collection lines, String lineEnding),這個用法用于將內存中一個集合的內容持久化到本地文件,以行的方式寫入每一個集合元素。可以指定編碼和換行符。

    這個方法的適用場景類似于:將內存中的一批“客戶信息集合”導出到文件中
    public static void writeLines(File file, String encoding, Collection lines, String lineEnding) throws IOException {
            OutputStream out 
    = null;
            
    try {
                out 
    = openOutputStream(file);
                IOUtils.writeLines(lines, lineEnding, out, encoding);
            }
     finally {
                IOUtils.closeQuietly(out);
            }

        }


    public static void writeLines(Collection lines, String lineEnding,
                OutputStream output, String encoding) 
    throws IOException {
            
    if (encoding == null{
                writeLines(lines, lineEnding, output);
            }
     else {
                
    if (lines == null{
                    
    return;
                }

                
    if (lineEnding == null{
                    lineEnding 
    = LINE_SEPARATOR;
                }

                
    for (Iterator it = lines.iterator(); it.hasNext(); ) {
                    Object line 
    = it.next();
                    
    if (line != null{
                        output.write(line.toString().getBytes(encoding));
                    }

                    output.write(lineEnding.getBytes(encoding));
                }

            }

        }

    void writeStringToFile(File file, String data, String encoding),這個方法將字符串一次性寫入文件
    public static void write(String data, OutputStream output, String encoding)
                
    throws IOException {
            
    if (data != null{
                
    if (encoding == null{
                    write(data, output);
                }
     else {
                    output.write(data.getBytes(encoding));
                }

            }

        }

    ④資源的比較

     ※ 文件時間比較
    boolean isFileNewer(File file, Date/File/Long) 和boolean isFileOlder(File file, Date/File/Long)兩種方法,這兩種方法的內部都是采用文件的last modify time進行比較的。

     ※ 文件內容比較
    boolean contentEquals(File file1, File file2)采用逐字節比較的方式,在正式比較內容之前,會先比較以下項目:存在性、類型、長度、鏈接指向,最后才是比較內容
    InputStream input1 = null;
            InputStream input2 
    = null;
            
    try {
                input1 
    = new FileInputStream(file1);
                input2 
    = new FileInputStream(file2);
                
    return IOUtils.contentEquals(input1, input2);

            }
     finally {
                IOUtils.closeQuietly(input1);
                IOUtils.closeQuietly(input2);
            }


        
    public static boolean contentEquals(InputStream input1, InputStream input2)
                
    throws IOException {
            
    if (!(input1 instanceof BufferedInputStream)) {
                input1 
    = new BufferedInputStream(input1);
            }

            
    if (!(input2 instanceof BufferedInputStream)) {
                input2 
    = new BufferedInputStream(input2);
            }


            
    int ch = input1.read();
            
    while (-1 != ch) {
                
    int ch2 = input2.read();
                
    if (ch != ch2) {
                    
    return false;
                }

                ch 
    = input1.read();
            }


            
    int ch2 = input2.read();
            
    return (ch2 == -1);
        }

    ⑤資源的過濾

    FileUtils提供了兩種類型的方法讓使用者可以輕松地過濾文件、目錄。它們分別是:

     ※ 基于Iterator形式的過濾
    iterateFiles(File directory, IOFileFilter fileFilter, IOFileFilter dirFilter),這個方法用于從指定的目錄下過濾文件。通過fileFilter我們可以指定要過濾的文件類型,通過dirFilter我們可以指定是否對子目錄進行同樣的過濾。如果為null則子目錄不參與過濾。

    iterateFiles(File directory, String[] extensions, boolean recursive),這個方法用于從指定的目錄下過濾文件。通過extensions我們可以指定要過濾的文件擴展名,通過recurisve我們可以指定是否對子目錄進行同樣的過濾。如果為false則子目錄不參與過濾。

     ※ 基于Collection形式的過濾
    listFiles(File directory, IOFileFilter fileFilter, IOFileFilter dirFilter),這個方法和基于Iterator形式的過濾相同,只是返回的值是一個集合。

    listFiles(File directory, String[] extensions, boolean recursive)
    ,這個方法和基于Iterator形式的過濾相同,只是返回的值是一個集合。

    ⑥資源的轉換


     從URL形式到File形式的轉換
    File toFile(URL url),這個轉換會首先將file://這個Prefix去掉,然后使用normalize方法對路徑進行規范。

     ※ 從File形式到URL形式的轉換
    URL[] toURLs(File[] files),這個轉換或對文件的路徑加上file://這個prefix,然后對路徑進行規范。


    -------------------------------------------------------------
    生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
    posted on 2010-03-08 15:07 Paul Lin 閱讀(6583) 評論(1)  編輯  收藏 所屬分類: J2SE


    FeedBack:
    # re: 【Java基礎專題】IO與文件讀寫---使用Apache commons IO簡化文件讀寫
    2015-09-24 10:29 | 阿斯蘭
    不錯  回復  更多評論
      
    <2010年3月>
    28123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    常用鏈接

    留言簿(21)

    隨筆分類

    隨筆檔案

    BlogJava熱點博客

    好友博客

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 成全视频免费观看在线看| 日韩在线免费播放| 亚洲人片在线观看天堂无码| 午夜国产大片免费观看| 一级毛片免费播放| 亚洲AV无码国产剧情| 亚洲av永久无码精品网站 | 日韩中文无码有码免费视频 | 一级片在线免费看| 久久精品国产亚洲AV网站| 女人被免费视频网站| 少妇性饥渴无码A区免费| 亚洲色成人四虎在线观看| 久久久久国产亚洲AV麻豆| AA免费观看的1000部电影| www.xxxx.com日本免费| 亚洲www在线观看| 国产AV无码专区亚洲A∨毛片| 永久免费无码网站在线观看| 老汉精品免费AV在线播放| 日本视频免费观看| 亚洲色图激情文学| 精品亚洲A∨无码一区二区三区| www国产亚洲精品久久久日本| 日日麻批免费40分钟日本的| 91在线免费视频| 美女视频免费看一区二区| 亚洲一区二区三区高清视频| 亚洲成A人片在线观看无码不卡| 国产一级一片免费播放| 永久免费的网站在线观看| 久久免费的精品国产V∧| 国产免费AV片在线观看播放| 色天使色婷婷在线影院亚洲| 亚洲免费观看在线视频| 亚洲一区二区三区日本久久九| 在线a亚洲v天堂网2019无码| 亚洲AV无码一区二三区| 日本xxwwxxww在线视频免费| 日韩精品福利片午夜免费观着| 中文字幕免费观看|