Apache Commons IO入門教程
Apache Commons IO是Apache基金會創建并維護的Java函數庫。它提供了許多類使得開發者的常見任務變得簡單,同時減少重復(boiler-plate)代碼,這些代碼可能遍布于每個獨立的項目中,你卻不得不重復的編寫。這些類由經驗豐富的開發者維護,對各種問題的邊界條件考慮周到,并持續修復相關bug。
在下面的例子中,我們會向你演示一些不同功能的方法,這些功能都是在org.apache.commons.io包下。Apache Commons IO 是一個巨大工程,我們不會深入去剖析它的底層原理,但是會演示一些比較常用的例子,不管你是不是新手,相信這些例子都會對你有所幫助。
1. Apache Commons IO 示例
</div>我們分別會用幾段代碼來演示下面的功能,每部分功能都代表Apache Commons IO所覆蓋的一個單獨領域,具體如下:
- 工具類
- 輸入
- 輸出
- 過濾器
- 比較器
- 文件監控器
為了更方便讀者進行理解,我們會把創建的每個類的輸出進行單獨展示。并且會把示例中功能演示所用到的到文件放到工程目錄(ExampleFolder目錄)中。
注意:為了能使用org.apache.commons.io中的功能,你首先需要下載jar包(請點擊這里),并且將jar包添加到Eclipse工程的編譯路徑下,右鍵點工程文件夾 -> Build Path -> Add external archives。
public class ApacheCommonsExampleMain { public static void main(String[] args) { UtilityExample.runExample(); FileMonitorExample.runExample(); FiltersExample.runExample(); InputExample.runExample(); OutputExample.runExample(); ComparatorExample.runExample(); } }
這個main方法會運行所有的示例,你可以將其他行的代碼注釋來執行你想要的示例。
1.1 Utility Classes
FilenameUtils:
這個工具類是用來處理文件名(譯者注:包含文件路徑)的,他可以輕松解決不同操作系統文件名稱規范不同的問題(比如windows和Unix)(在Unix系統以及Linux系統中文件分隔符是“/”,不支持”\“,windows中支持”\“以及”/“)。
FileSystemUtils:提供查看指定目錄剩余空間的方法。
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:UsersLilykosworkspaceApacheCommonsExampleExampleFolderexampleTxt.txt"; private static final String PARENT_DIR = "C:UsersLilykosworkspaceApacheCommonsExample"; 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:UsersLilykosworkspaceApacheCommonsExampleExampleFolder 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
1.2 文件監控器
org.apache.commons.io.monitor包下的類包含的方法可以獲取文件的指定信息,不過更重要的是,它可以創建處理器(handler)來跟蹤指定文件或目錄的變化并且可以在文件或目錄發生變化的時候進行一些操作。讓我們來看看下面的代碼:
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:UsersLilykosworkspaceApacheCommonsExampleExampleFolderexampleFileEntry.txt"; private static final String PARENT_DIR = "C:UsersLilykosworkspaceApacheCommonsExampleExampleFolder"; private static final String NEW_DIR = "C:UsersLilykosworkspaceApacheCommonsExampleExampleFoldernewDir"; private static final String NEW_FILE = "C:UsersLilykosworkspaceApacheCommonsExampleExampleFoldernewFile.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:UsersLilykosworkspaceApacheCommonsExampleExampleFolderexampleFileEntry.txt File name: exampleFileEntry.txt Is the file a directory?: false Directory created: newDir File created: newFile.txt Directory deleted: newDir File deleted: newFile.tx
讓我們來看看這里發生了什么,我們使用org.apache.commons.io.monitor包下的類創建了一個處理器來監聽一些特定的事件(在上面的例子中就是我們對文件或目錄所做的所有操作事件),為了獲得這些信息,我們需要做以下幾步操作:
1、創建一個File對象,這個對象指向我們需要監聽變化的目錄。
2、創建一個FileAlterationObserver對象,這個對象會觀察這些變化。
3、通過調用addListener()方法,為observer對象添加一個 FileAlterationListenerAdaptor對象。你可以通過很多種方式來創建一個適配器,在我們的例子中我們使用內部類的方式進行創建并且只實現其中的一部分方法(只需要實現我們例子中需要用的方法即可)。
4、創建一個FileAlterationMonitor 對象,將已經創建好的observer對象添加其中并且傳入時間間隔參數(單位是毫秒)。
1.3 過濾器
過濾器可以以組合的方式使用并且它的用途非常多樣。它可以輕松的區分不同的文件并且找到滿足我們條件的文件。我們可以組合不同的過濾器來執行文件的邏輯比較并且精確的獲取我們所需要文件,而無需使用冗余的字符串比較來尋找我們的文件。
FiltersExample.java
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:UsersLilykosworkspaceApacheCommonsExampleExampleFolder"; 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
1.4 比較器
使用org.apache.commons.io.comparator
包下的類可以讓你輕松的對文件或目錄進行比較或者排序。你只需提供一個文件列表,選擇不同的類就可以實現不同方式的文件比較。
ComparatorExample.java
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:UsersLilykosworkspaceApacheCommonsExampleExampleFolder"; private static final String FILE_1 = "C:UsersLilykosworkspaceApacheCommonsExampleExampleFolderexample"; private static final String FILE_2 = "C:UsersLilykosworkspaceApacheCommonsExampleExampleFolderexampleTxt.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:UsersLilykosworkspaceApacheCommonsExampleExampleFoldercomparator1.txt C:UsersLilykosworkspaceApacheCommonsExampleExampleFoldercomperator2.txt C:UsersLilykosworkspaceApacheCommonsExampleExampleFolderexample C:UsersLilykosworkspaceApacheCommonsExampleExampleFolderexampleFileEntry.txt C:UsersLilykosworkspaceApacheCommonsExampleExampleFolderexampleTxt.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
讓我們來看看這里用到了哪些類:
NameFileComparator:通過文件名來比較文件。
SizeFileComparator:通過文件大小來比較文件。
LastModifiedFileComparator:通過文件的最新修改時間來比較文件。
在這里你需要注意,比較可以在定的文件夾中(文件夾下的文件已經被sort()方法排序過了),也可以在兩個指定的文件之間(通過使用compare()方法)。
1.5 輸入
在org.apache.commons.io.input包下有許多InputStrem類的實現,我們來測試一個最實用的類,TeeInputStream,將InputStream以及OutputStream作為參數傳入其中,自動實現將輸入流的數據讀取到輸出流中。而且,通過傳入第三個參數,一個boolean類型參數,可以在數據讀取完畢之后自動關閉輸入流和輸出流。
InputExample.java
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:UsersLilykosworkspaceApacheCommonsExampleInputOutputExampleFolderweb.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.
1.6 輸出
與org.apache.commons.io.input包中的類相似, org.apache.commons.io.output包中同樣有OutputStream類的實現,他們可以在多種情況下使用,一個非常有意思的類就是 TeeOutputStream,它可以將輸出流進行分流,換句話說我們可以用一個輸入流將數據分別讀入到兩個不同的輸出流。
OutputExample.java
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.
2. 下載完整的示例
原文鏈接: Apache Commons IO入門教程 翻譯: ImportNew.com - yewenhai
譯文鏈接: http://www.importnew.com/13715.html