標籤:blog http io ar os java sp for strong
雖然Google的guava對Java的IO操作進行了一定封裝,但是它更偏向於集合、並發和緩衝,在實際項目中,我非常喜歡guava,同時我也非常喜歡Apache的一個工具包org.apache.commons.io,這兩個工具包提供非常強大的工具能力,能夠簡化代碼邏輯,提高開發效率和品質,是每個Java程式員都應該掌握的工具包。此文簡單介紹一下org.apache.commons.io,詳細的可參考其API注,此文絕大部分內容翻譯自http://www.javacodegeeks.com/2014/10/apache-commons-io-tutorial.html,感興趣的查看原文,本文源碼請移步
Apache Commons IO是Apache開源的一個工具包,其封裝了對IO的常見操作,使開發人員只需要少量的代碼就能完成大量的IO操作,此文主要介紹如下幾個工具類
- Utility classes
- Input
- Output
- Filters
- Comparators
- File Monitor
目前org.apache.commons.io2.4版本並未託管到Maven庫,所以需要自行下載然後將下載的commons-io-2.4.jar添加到環境變數中
1、Utils(FileUtils,FilenameUtils,FileSystemUtils)這三個類主要提供了對檔案、檔案名稱及檔案系統的操作,API非常簡單,通過API名稱都能知道其作用,
樣本如下
//檔案絕對路徑 private static final String EXAMPLE_TXT_PATH = "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio/commonio.txt"; //檔案父目錄 private static final String PARENT_DIR = "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio"; 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類樣本 // 通過FileUtils.getFile(String)建立File對象,然後根據FileUtils.lineIterator(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(); // 目錄是否已經包含檔案 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("/Users")); System.out.println("Free disk space (in MB): " + FileSystemUtils.freeSpaceKb("/Users") / 1024); }
2、InputStream,其提供了XmlStreamReader工具類,能夠擷取xml的檔案編碼等操作,
樣本如下
private static final String XML_PATH = "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio/test.xml"; public static void runExample() { System.out.println("Input example..."); XmlStreamReader xmlReader = null; try { // XmlStreamReader:讀取一個xml檔案,提供了過去檔案編碼API File xml = FileUtils.getFile(XML_PATH); xmlReader = new XmlStreamReader(xml); System.out.println("XML encoding: " + xmlReader.getEncoding()); } catch (IOException e) { e.printStackTrace(); } finally { try { xmlReader.close(); } catch (IOException e) { e.printStackTrace(); } } }3、Output,其提供的TeeInputStream,TeeOutputStream類能將輸入資料流快速拷貝到輸出資料流中
private static final String INPUT = "This should go to the output."; public static void runExample() { System.out.println("Output example..."); TeeInputStream tee=null; TeeInputStream teeIn = null; TeeOutputStream teeOut = null; try { //TeeInputStream能將輸入資料流快速拷貝到輸出資料流中 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()); //能將輸入資料流同時拷貝到兩個輸出資料流 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 { //此處不需要關閉teeOut,當關閉teeIn時,同時會關閉teeOut try { teeIn.close(); tee.close();} catch (IOException e) { e.printStackTrace(); } } }
4、Filters,commons-io提供了多種過濾器,能夠根據條件過濾指定目錄下的檔案,同時還支援過濾器組合,
樣本如下
private static final String PARENT_DIR = "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio"; public static void runExample() { System.out.println("File Filter example..."); // NameFileFilter:擷取指定目錄下,符合給定檔案清單的檔案 //例如擷取此例,擷取PARENT_DIR目錄下commonios和commonio.txt檔案 File dir = FileUtils.getFile(PARENT_DIR); String[] acceptedNames = {"commonios", "commonio.txt"}; for (String file: dir.list(new NameFileFilter(acceptedNames, IOCase.INSENSITIVE))) { System.out.println("File found, named: " + file); } //WildcardFileFilter:支援正則匹配,擷取指定目錄下,滿足正則的檔案 for (String file: dir.list(new WildcardFileFilter("*common*"))) { System.out.println("Wildcard file found, named: " + file); } // PrefixFileFilter:擷取以給定字串為首碼的檔案名稱 for (String file: dir.list(new PrefixFileFilter("common"))) { System.out.println("Prefix file found, named: " + file); } // SuffixFileFilter::擷取以給定字串為尾碼的檔案名稱 for (String file: dir.list(new SuffixFileFilter(".txt"))) { System.out.println("Suffix file found, named: " + file); } // OrFileFilter:支援傳入多個過濾器,過濾器之間是或的關係 for (String file: dir.list(new OrFileFilter( new WildcardFileFilter("*ample*"), new SuffixFileFilter(".txt")))) { System.out.println("Or file found, named: " + file); } //AndFileFilter:支援傳入多個過濾器,過濾器之間是且的關係 for (String file: dir.list(new AndFileFilter( new WildcardFileFilter("*ample*"), new NotFileFilter(new SuffixFileFilter(".txt"))))) { System.out.println("And/Not file found, named: " + file); } }
5、Comparators,commons-io提供了多種檔案比較工具類,能夠根據檔案名稱、檔案大小、修改時間等對目錄下的檔案進行排序,
簡單樣本如下
private static final String PARENT_DIR = "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio"; private static final String FILE_1 = "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio/commonio.txt"; private static final String FILE_2 = "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio/test.xml"; public static void runExample() { System.out.println("Comparator example..."); //NameFileComparator:根據檔案名稱排序,IOCase表示是否大小寫敏感 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:根據檔案大小排序,小檔案在前,其構造器支援傳一個boolean類型的參數, //true表示需要計算該目錄下的目錄大小 //flase表示不需要計算該目錄下的目錄大小(0) 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:根據修改時間排序,最新修改排前 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); } }
6、File Monitor,commons-io還提供了對目錄的監控類,可以對指定目錄進行監控,如果目錄下檔案發生變化(修改,增加,刪除等),其監控會向監聽器發送相應的事件。
樣本如下
private static final String EXAMPLE_PATH = "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio/commonio.txt"; private static final String PARENT_DIR = "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio"; private static final String NEW_DIR = "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio/newDir"; private static final String NEW_FILE = "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio/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 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()); } }); // 建立一個每隔500毫秒就做一次檢查的監控 FileAlterationMonitor monitor = new FileAlterationMonitor(500, observer); try { monitor.start(); //啟動監控後,對監控目錄做一些檔案操作,觸發監聽器 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(); } }以上只是對commons-io的一個簡單介紹,從中可以看出該工具包提供了強大的IO操作,更多功能還需實際項目中不斷探索
Apache Commons IO簡介