Apache Commons IO 示例

Apache Commons IO是由Apache Foundation維護的java庫,它提供了多種類庫使開發者能夠很容易地完成一些常見的任務,簡化那些被反覆的樣板化的代碼。這個類庫的重要性是巨大的,因爲它非常成熟,並且由有經驗的開發者維護,他們會考慮到各種情形,和修復他們遇到的不同種類的bug。

下面會展示org.apache.commons.io包的幾個不同功能,下面的代碼會分成以下幾類,每一類都表示Apache Commons IO所覆蓋的領域,這些領域包括:
- Utility classes
- Input
- Output
- Filters
- Comparators
- File Monitor

Utility classes

org.apache.commons.io中有不同的工具類,幾種大多數跟文件操作和字符串比較相關,下面給出最重要的幾個:
- FilenameUtils:這個類主要處理文件名, 在Unix和Windows上同樣適用;
- FileUtils: 提供了文件操作的方法(移動、打開和讀取、檢查文件是否存在等);
- IOCase: 字符串的操作和比較;
- FileSystemUtils:它的方法主要返回指定驅動的空閒空間;

Utility代碼示例:

import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileSystemUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.LineIterator;
import org.apache.commons.io.IOCase;
public final class UtilityExample {
    // We are using the file exampleTxt.txt in the folder ExampleFolder,
    // and we need to provide the full path to the Utility classes.
    private static final String EXAMPLE_TXT_PATH =
            "C:\\Users\\Lilykos\\workspace\\ApacheCommonsExample\\ExampleFolder\\exampleTxt.txt";
    private static final String PARENT_DIR =
            "C:\\Users\\Lilykos\\workspace\\ApacheCommonsExample";
    public static void runExample() throws IOException {
        System.out.println("Utility Classes example...");
        // FilenameUtils
        System.out.println("Full path of exampleTxt: " +
                FilenameUtils.getFullPath(EXAMPLE_TXT_PATH));
        System.out.println("Full name of exampleTxt: " +
                FilenameUtils.getName(EXAMPLE_TXT_PATH));
        System.out.println("Extension of exampleTxt: " +
                FilenameUtils.getExtension(EXAMPLE_TXT_PATH));
        System.out.println("Base name of exampleTxt: " +
                FilenameUtils.getBaseName(EXAMPLE_TXT_PATH));
        // FileUtils
        // We can create a new File object using FileUtils.getFile(String)
        // and then use this object to get information from the file.
        File exampleFile = FileUtils.getFile(EXAMPLE_TXT_PATH);
        LineIterator iter = FileUtils.lineIterator(exampleFile);
        System.out.println("Contents of exampleTxt...");
        while (iter.hasNext()) {
            System.out.println("\t" + iter.next());
        }
        iter.close();
        // We can check if a file exists somewhere inside a certain directory.
        File parent = FileUtils.getFile(PARENT_DIR);
        System.out.println("Parent directory contains exampleTxt file: " +
                FileUtils.directoryContains(parent, exampleFile));
        // IOCase
        String str1 = "This is a new String.";
        String str2 = "This is another new String, yes!";
        System.out.println("Ends with string (case sensitive): " +
                IOCase.SENSITIVE.checkEndsWith(str1, "string."));
        System.out.println("Ends with string (case insensitive): " +
                IOCase.INSENSITIVE.checkEndsWith(str1, "string."));
        System.out.println("String equality: " +
                IOCase.SENSITIVE.checkEquals(str1, str2));
        // FileSystemUtils
        System.out.println("Free disk space (in KB): " + FileSystemUtils.freeSpaceKb("C:"));
        System.out.println("Free disk space (in MB): " + FileSystemUtils.freeSpaceKb("C:") / 1024);
    }
}

輸出:

Utility Classes example...
Full path of exampleTxt: C:\Users\Lilykos\workspace\ApacheCommonsExample\ExampleFolder\
Full name of exampleTxt: exampleTxt.txt
Extension of exampleTxt: txt
Base name of exampleTxt: exampleTxt
Contents of exampleTxt...
    This is an example text file.
    We will use it for experimenting with Apache Commons IO.
Parent directory contains exampleTxt file: true
Ends with string (case sensitive): false
Ends with string (case insensitive): true
String equality: false
Free disk space (in KB): 32149292
Free disk space (in MB): 31395

File Monitor

org.apache.commons.io.monitor包含了獲取文件的特定信息,但是更重要的是它能夠創建handlers,用於最終特定文件或文件夾的變化,示例如下:

import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileDeleteStrategy;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.apache.commons.io.monitor.FileEntry;
public final class FileMonitorExample {
    private static final String EXAMPLE_PATH =
            "C:\\Users\\Lilykos\\workspace\\ApacheCommonsExample\\ExampleFolder\\exampleFileEntry.txt";
    private static final String PARENT_DIR =
            "C:\\Users\\Lilykos\\workspace\\ApacheCommonsExample\\ExampleFolder";
    private static final String NEW_DIR =
            "C:\\Users\\Lilykos\\workspace\\ApacheCommonsExample\\ExampleFolder\\newDir";
    private static final String NEW_FILE =
            "C:\\Users\\Lilykos\\workspace\\ApacheCommonsExample\\ExampleFolder\\newFile.txt";
    public static void runExample() {
        System.out.println("File Monitor example...");
        // FileEntry
        // We can monitor changes and get information about files
        // using the methods of this class.
        FileEntry entry = new FileEntry(FileUtils.getFile(EXAMPLE_PATH));
        System.out.println("File monitored: " + entry.getFile());
        System.out.println("File name: " + entry.getName());
        System.out.println("Is the file a directory?: " + entry.isDirectory());
        // File Monitoring
        // Create a new observer for the folder and add a listener
        // that will handle the events in a specific directory and take action.
        File parentDir = FileUtils.getFile(PARENT_DIR);
        FileAlterationObserver observer = new FileAlterationObserver(parentDir);
        observer.addListener(new FileAlterationListenerAdaptor() {
                @Override
                public void onFileCreate(File file) {
                    System.out.println("File created: " + file.getName());
                }
                @Override
                public void onFileDelete(File file) {
                    System.out.println("File deleted: " + file.getName());
                }
                @Override
                public void onDirectoryCreate(File dir) {
                    System.out.println("Directory created: " + dir.getName());
                }
                @Override
                public void onDirectoryDelete(File dir) {
                    System.out.println("Directory deleted: " + dir.getName());
                }
        });
        // Add a monior that will check for events every x ms,
        // and attach all the different observers that we want.
        FileAlterationMonitor monitor = new FileAlterationMonitor(500, observer);
        try {
            monitor.start();
            // After we attached the monitor, we can create some files and directories
            // and see what happens!
            File newDir = new File(NEW_DIR);
            File newFile = new File(NEW_FILE);
            newDir.mkdirs();
            newFile.createNewFile();
            Thread.sleep(1000);
            FileDeleteStrategy.NORMAL.delete(newDir);
            FileDeleteStrategy.NORMAL.delete(newFile);
            Thread.sleep(1000);
            monitor.stop();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

輸出:

File Monitor example...
File monitored: C:\Users\Lilykos\workspace\ApacheCommonsExample\ExampleFolder\exampleFileEntry.txt
File name: exampleFileEntry.txt
Is the file a directory?: false
Directory created: newDir
File created: newFile.txt
Directory deleted: newDir
File deleted: newFile.txt

在這裏我們使用org.apache.commons.io.monitor包創建了handlers用來監聽特定的事件,爲了實現該目標,主要有一下幾步:
- 創建File對象,然後應用到想要監聽的目錄上;
- 創建FileAlterationObserver對象,它負責觀察這些變化;
- 使用addListener()方法添加FileAlterationListenerAdaptor觀察者;
- 創建FileAlterationMonitor並添加觀察者;
- 使用start()方法啓動monitor,必要的時候使用stop()方法終止它。

Filters

Filters主要用於不同文件的區分,得到滿足特定條件的文件。而且也可以聯合多個filters執行邏輯比較,獲取更加精準的文件類型。
Filters 示例:

import java.io.File;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOCase;
import org.apache.commons.io.filefilter.AndFileFilter;
import org.apache.commons.io.filefilter.NameFileFilter;
import org.apache.commons.io.filefilter.NotFileFilter;
import org.apache.commons.io.filefilter.OrFileFilter;
import org.apache.commons.io.filefilter.PrefixFileFilter;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.apache.commons.io.filefilter.WildcardFileFilter;
public final class FiltersExample {
    private static final String PARENT_DIR =
            "C:\\Users\\Lilykos\\workspace\\ApacheCommonsExample\\ExampleFolder";
    public static void runExample() {
        System.out.println("File Filter example...");
        // NameFileFilter
        // Right now, in the parent directory we have 3 files:
        //      directory example
        //      file exampleEntry.txt
        //      file exampleTxt.txt
        // Get all the files in the specified directory
        // that are named "example".
        File dir = FileUtils.getFile(PARENT_DIR);
        String[] acceptedNames = {"example", "exampleTxt.txt"};
        for (String file: dir.list(new NameFileFilter(acceptedNames, IOCase.INSENSITIVE))) {
            System.out.println("File found, named: " + file);
        }
        //WildcardFileFilter
        // We can use wildcards in order to get less specific results
        //      ? used for 1 missing char
        //      * used for multiple missing chars
        for (String file: dir.list(new WildcardFileFilter("*ample*"))) {
            System.out.println("Wildcard file found, named: " + file);
        }
        // PrefixFileFilter
        // We can also use the equivalent of startsWith
        // for filtering files.
        for (String file: dir.list(new PrefixFileFilter("example"))) {
            System.out.println("Prefix file found, named: " + file);
        }
        // SuffixFileFilter
        // We can also use the equivalent of endsWith
        // for filtering files.
        for (String file: dir.list(new SuffixFileFilter(".txt"))) {
            System.out.println("Suffix file found, named: " + file);
        }
        // OrFileFilter
        // We can use some filters of filters.
        // in this case, we use a filter to apply a logical
        // or between our filters.
        for (String file: dir.list(new OrFileFilter(
                new WildcardFileFilter("*ample*"), new SuffixFileFilter(".txt")))) {
            System.out.println("Or file found, named: " + file);
        }
        // And this can become very detailed.
        // Eg, get all the files that have "ample" in their name
        // but they are not text files (so they have no ".txt" extension.
        for (String file: dir.list(new AndFileFilter( // we will match 2 filters...
                new WildcardFileFilter("*ample*"), // ...the 1st is a wildcard...
                new NotFileFilter(new SuffixFileFilter(".txt"))))) { // ...and the 2nd is NOT .txt.
            System.out.println("And/Not file found, named: " + file);
        }
    }
}

輸出:

File Filter example...
File found, named: example
File found, named: exampleTxt.txt
Wildcard file found, named: example
Wildcard file found, named: exampleFileEntry.txt
Wildcard file found, named: exampleTxt.txt
Prefix file found, named: example
Prefix file found, named: exampleFileEntry.txt
Prefix file found, named: exampleTxt.txt
Suffix file found, named: exampleFileEntry.txt
Suffix file found, named: exampleTxt.txt
Or file found, named: example
Or file found, named: exampleFileEntry.txt
Or file found, named: exampleTxt.txt
And/Not file found, named: example

Comparators

org.apache.commons.io.comparator包用於簡單比較和排序文件和目錄。

Comparators示例:

import java.io.File;
import java.util.Date;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOCase;
import org.apache.commons.io.comparator.LastModifiedFileComparator;
import org.apache.commons.io.comparator.NameFileComparator;
import org.apache.commons.io.comparator.SizeFileComparator;
public final class ComparatorExample {
    private static final String PARENT_DIR =
            "C:\\Users\\Lilykos\\workspace\\ApacheCommonsExample\\ExampleFolder";
    private static final String FILE_1 =
            "C:\\Users\\Lilykos\\workspace\\ApacheCommonsExample\\ExampleFolder\\example";
    private static final String FILE_2 =
            "C:\\Users\\Lilykos\\workspace\\ApacheCommonsExample\\ExampleFolder\\exampleTxt.txt";
    public static void runExample() {
        System.out.println("Comparator example...");
        //NameFileComparator
        // Let's get a directory as a File object
        // and sort all its files.
        File parentDir = FileUtils.getFile(PARENT_DIR);
        NameFileComparator comparator = new NameFileComparator(IOCase.SENSITIVE);
        File[] sortedFiles = comparator.sort(parentDir.listFiles());
        System.out.println("Sorted by name files in parent directory: ");
        for (File file: sortedFiles) {
            System.out.println("\t"+ file.getAbsolutePath());
        }
        // SizeFileComparator
        // We can compare files based on their size.
        // The boolean in the constructor is about the directories.
        //      true: directory's contents count to the size.
        //      false: directory is considered zero size.
        SizeFileComparator sizeComparator = new SizeFileComparator(true);
        File[] sizeFiles = sizeComparator.sort(parentDir.listFiles());
        System.out.println("Sorted by size files in parent directory: ");
        for (File file: sizeFiles) {
            System.out.println("\t"+ file.getName() + " with size (kb): " + file.length());
        }
        // LastModifiedFileComparator
        // We can use this class to find which file was more recently modified.
        LastModifiedFileComparator lastModified = new LastModifiedFileComparator();
        File[] lastModifiedFiles = lastModified.sort(parentDir.listFiles());
        System.out.println("Sorted by last modified files in parent directory: ");
        for (File file: lastModifiedFiles) {
            Date modified = new Date(file.lastModified());
            System.out.println("\t"+ file.getName() + " last modified on: " + modified);
        }
        // Or, we can also compare 2 specific files and find which one was last modified.
        //      returns > 0 if the first file was last modified.
        //      returns  0)
            System.out.println("File " + file1.getName() + " was modified last because...");
        else
            System.out.println("File " + file2.getName() + "was modified last because...");
        System.out.println("\t"+ file1.getName() + " last modified on: " +
                new Date(file1.lastModified()));
        System.out.println("\t"+ file2.getName() + " last modified on: " +
                new Date(file2.lastModified()));
    }
}

輸出:

Comparator example...
Sorted by name files in parent directory:
    C:\Users\Lilykos\workspace\ApacheCommonsExample\ExampleFolder\comparator1.txt
    C:\Users\Lilykos\workspace\ApacheCommonsExample\ExampleFolder\comperator2.txt
    C:\Users\Lilykos\workspace\ApacheCommonsExample\ExampleFolder\example
    C:\Users\Lilykos\workspace\ApacheCommonsExample\ExampleFolder\exampleFileEntry.txt
    C:\Users\Lilykos\workspace\ApacheCommonsExample\ExampleFolder\exampleTxt.txt
Sorted by size files in parent directory:
    example with size (kb): 0
    exampleTxt.txt with size (kb): 87
    exampleFileEntry.txt with size (kb): 503
    comperator2.txt with size (kb): 1458
    comparator1.txt with size (kb): 4436
Sorted by last modified files in parent directory:
    exampleTxt.txt last modified on: Sun Oct 26 14:02:22 EET 2014
    example last modified on: Sun Oct 26 23:42:55 EET 2014
    comparator1.txt last modified on: Tue Oct 28 14:48:28 EET 2014
    comperator2.txt last modified on: Tue Oct 28 14:48:52 EET 2014
    exampleFileEntry.txt last modified on: Tue Oct 28 14:53:50 EET 2014
File example was modified last because...
    example last modified on: Sun Oct 26 23:42:55 EET 2014
    exampleTxt.txt last modified on: Sun Oct 26 14:02:22 EET 2014

Input

org.apache.commons.io.input包中有多種對InputStream的實現。下面給出一個最實用的TeeInputStream,利用InputStreamOutputStream的參數自動拷貝輸入讀取的字節到輸出。而且使用第三個boolean參數,用來最終關閉TeeInputStream,InputStreamOutputStream

Input示例:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.input.TeeInputStream;
import org.apache.commons.io.input.XmlStreamReader;
public final class InputExample {
    private static final String XML_PATH =
            "C:\\Users\\Lilykos\\workspace\\ApacheCommonsExample\\InputOutputExampleFolder\\web.xml";
    private static final String INPUT = "This should go to the output.";
    public static void runExample() {
        System.out.println("Input example...");
        XmlStreamReader xmlReader = null;
        TeeInputStream tee = null;
        try {
            // XmlStreamReader
            // We can read an xml file and get its encoding.
            File xml = FileUtils.getFile(XML_PATH);
            xmlReader = new XmlStreamReader(xml);
            System.out.println("XML encoding: " + xmlReader.getEncoding());
            // TeeInputStream
            // This very useful class copies an input stream to an output stream
            // and closes both using only one close() method (by defining the 3rd
            // constructor parameter as true).
            ByteArrayInputStream in = new ByteArrayInputStream(INPUT.getBytes("US-ASCII"));
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            tee = new TeeInputStream(in, out, true);
            tee.read(new byte[INPUT.length()]);
            System.out.println("Output stream: " + out.toString());         
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try { xmlReader.close(); }
            catch (IOException e) { e.printStackTrace(); }
            try { tee.close(); }
            catch (IOException e) { e.printStackTrace(); }
        }
    }
}

輸出:

Input example...
XML encoding: UTF-8
Output stream: This should go to the output.

Output

org.apache.commons.io.input類似,org.apache.commons.io.output 實現了OutputStream,用於不同的場景。TeeOutputStream允許輸出流進行分支,也就是把一個輸入流發送到兩個不同的輸出流上。

Output示例:

import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import org.apache.commons.io.input.TeeInputStream;
 import org.apache.commons.io.output.TeeOutputStream;
 public final class OutputExample {
     private static final String INPUT = "This should go to the output.";
     public static void runExample() {
         System.out.println("Output example...");
         TeeInputStream teeIn = null;
         TeeOutputStream teeOut = null;
         try {
             // TeeOutputStream
             ByteArrayInputStream in = new ByteArrayInputStream(INPUT.getBytes("US-ASCII"));
             ByteArrayOutputStream out1 = new ByteArrayOutputStream();
             ByteArrayOutputStream out2 = new ByteArrayOutputStream();
             teeOut = new TeeOutputStream(out1, out2);
             teeIn = new TeeInputStream(in, teeOut, true);
             teeIn.read(new byte[INPUT.length()]);
             System.out.println("Output stream 1: " + out1.toString());
             System.out.println("Output stream 2: " + out2.toString());
         } catch (IOException e) {
             e.printStackTrace();
         } finally {
             // No need to close teeOut. When teeIn closes, it will also close its
             // Output stream (which is teeOut), which will in turn close the 2
             // branches (out1, out2).
             try { teeIn.close(); }
             catch (IOException e) { e.printStackTrace(); }
         }
     }
 }

輸出:

 Output example...
 Output stream 1: This should go to the output.
 Output stream 2: This should go to the output.

原文:Apache Commons IO Tutorial: A beginner’s guide

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