632
技術社區[雲棲]
Commons IO 官方文檔
Common IO 是一個工具庫,用來幫助開發IO功能 它包括6個主要部分
- Utility classes – 包括一些靜態方法來執行常用任務
-
Input –
InputStream
和Reader
實現 -
Output –
OutputStream
和Writer
實現 -
Filters – 多種文件過濾器實現(定義了
IOFileFilter
接口,同時繼承了FileFilter
和FilenameFilter
接口) -
Comparators – 用於文件比較的多種
java.util.Comparatot
實現
發行版本
- Commons IO 2.5 (requires JDK 1.6+)
- Commons IO 2.4 (requires JDK 1.6+)
- Commons IO 2.2 (requires JDK 1.5+)
用戶指南
Commons-IO 包括 工具類 (utility classes
), 字節序列類 (endian classes
), 行迭代器 (line iterator
), 文件過濾器 (file filters
),文件比較器 (file comparators
) 和 流實現 (stream implementations
).
Utility classes
IOUtils
IOUtils 包含一些工具類,用於處理讀,寫和拷貝,這些方法基於 InputStream
, OutputStream
, Reader
和 Writer
工作.
例如,思考一個任務,從URL中讀取byte數據,並打印。通常會這樣做:
InputStream in = new URL( "https://commons.apache.org" ).openStream();
try {
InputStreamReader inR = new InputStreamReader( in );
BufferedReader buf = new BufferedReader( inR );
String line;
while ( ( line = buf.readLine() ) != null ) {
System.out.println( line );
}
} finally {
in.close();
}
使用 IOUtils
類,可以這樣:
InputStream in = new URL( "https://commons.apache.org" ).openStream();
try {
System.out.println( IOUtils.toString( in ) );
} finally {
IOUtils.closeQuietly(in);
}
在某些應用領域,例如IO操作中是很常見的,這個類可以節省很多時間。並且你可以依賴於經過全麵測試的代碼。
對於這類的代碼,靈活性和速度是最重要的。然而你也應該明白這麼做的限製。使用以上的方式讀取一個1GB的文件將會試圖創造一個1GB字符串對象
FileUtils
FileUtils 包含一些工具類,它們基於File
對象工作,包括讀,寫,拷貝和比較文件
例如逐行讀取整個文件你可以使用:
File file = new File("/commons/io/project.properties");
List lines = FileUtils.readLines(file, "UTF-8");
FilenameUtils
FilenameUtils包含一些工具類,它們基於文件名工作而不是File
對象。這個類旨在 在Unix和Windows環境下保持一致,幫助在兩個環境下過渡(如從開發環境到生成環境)
例如,正常化文件名,刪除..
片段:
String filename = "C:/commons/io/../lang/project.xml";
String normalized = FilenameUtils.normalize(filename);
// result is "C:/commons/lang/project.xml"
FileSystemUtils
FileSystemUtils包含一些工具類,基於文件係統訪問功能不被JDK支持。目前,隻有一個方法就是得到驅動器空餘空間。注意這使用命令行而不是 native code。
例如得到驅動器空餘空間:
long freeSpace = FileSystemUtils.freeSpace("C:/");
Endian classes
不同的計算機架構對應字節序采用不同的約定,在所謂的”小端”架構(例如Intel),低位字節被存儲在內存的最低字節,之後的字節在高地址。對於”大端”架構(如Motoroal),情況相反。
在這個包中有兩個相關聯的類:
- EndianUtils 包含靜態方法來交換Java基本類型和流的字節序
-
SwappedDataInputStream實現了
DataInput
接口。可以從文件中讀取非本地字節序。
Line iterator
org.apache.commons.io.LineIterator
類提供類靈活的方式操作基於行的文件。通過FileUtils
或 IOUtils
中的工廠方法,可以直接創建一個實例。推薦的使用方法是:
LineIterator it = FileUtils.lineIterator(file, "UTF-8");
try {
while (it.hasNext()) {
String line = it.nextLine();
/// do something with line
}
} finally {
LineIterator.closeQuietly(iterator);
}
File filters
org.apache.commons.io.filefilter
包定義了一個接口 (IOFileFilter),同時繼承了 java.io.FileFilter
和 java.io.FilenameFilter
接口。除此之外還提供了一係列可以使用的IOFileFilter
接口實現,包括允許你組合其他過濾器。這些過濾器可以用來遍曆文件或在FileDialog
中使用。
詳情見 filefilter 包的Javadoc。
File comparators
org.apache.commons.io.comparator
包為java.io.File
提供一些java.util.Comparator
實現。這些比較器可以用來排序列表和文件數字。
詳情見 comparator 包的Javadoc。
Streams
org.apache.commons.io.input
和 org.apache.commons.io.output
包中包含一些有用的流實現。他們包括:
- Null output stream – 默默吸收所有發給它的數據
- Tee output stream – 發送輸出數據給兩個流而不是一個
- Byte array output stream – 這是一個比JDK更快的版本
- Counting streams – 計算通過的字節數
- Proxy streams – 在代理中委托正確的方法
- Lockable writer – 使用鎖文件提供寫入同步
最佳實踐
本文檔提供一些在IO領域的最佳實踐
java.io.File
通常,你要處理文件和文件名。有很多地方可能出錯:
- 一個類在Uinx下正常工作但是在Windows下不工作(反之亦然)
- 由於重複或丟失路徑分隔符造成無效的文件名
- 等等
這些都是不使用字符串類型文件名的充分理由。使用 java.io.File
可以很好的處理上述情況。因此,我們的最佳實踐建議對文件名使用 java.io.File
代替字符串來避免平台依賴。
commons-io 1.1開始包含一個專門用於文件名的處理類 – FilenameUtils。這會處理很多這類文件名問題,但是我們仍然建議盡可能的使用 java.io.File
對象
讓我們來看一個例子:
public static String getExtension(String filename) {
int index = filename.lastIndexOf('.');
if (index == -1) {
return "";
} else {
return filename.substring(index + 1);
}
}
很容易?是的,但是如果傳入一個全路徑而不隻是文件名會發生什麼?考慮一下,完全合法的路徑: “C:\Temp\documentation.new\README”。這個方法將會返回”new\README”,絕對不是你想要的
請使用 java.io.File
代替字符串作為文件名。這個類提供的方法經過了良好的測試。在 FileUtil
你會發現其他關於 java.io.File
有用的工具方法。
String tmpdir = "/var/tmp";
String tmpfile = tmpdir + System.getProperty("file.separator") + "test.tmp";
InputStream in = new java.io.FileInputStream(tmpfile);
替代
File tmpdir = new File("/var/tmp");
File tmpfile = new File(tmpdir, "test.tmp");
InputStream in = new java.io.FileInputStream(tmpfile);
Buffering streams
IO性能很多情況下取決於緩衝策略。通常以512或1024比特讀取數據塊會相當快,因為這些大小的數據塊和硬盤在文件係統中的數據塊大小或文件係統緩存很搭配。但是如果你隻需要讀取結果字節那麼性能會有顯著下降
確保你在讀取或寫入流時正確的進行緩衝,特別是使用文件時,隻在 BufferedInputStream
上包裝 FileInputStream
InputStream in = new java.io.FileInputStream(myfile);
try {
in = new java.io.BufferedInputStream(in);
in.read(.....
} finally {
IOUtils.closeQuietly(in);
}
注意不要緩衝一個已經被緩衝的流。一些組件例如 XML 解析器可能自己緩衝,所以裝飾傳遞給 XML 解析器的InputStream
隻會拖慢的代碼。如果你使用我們的 CopyUtils
或者 IOUitls
你不需要另外緩衝,你使用的代碼在複製過程的已經緩衝。經常檢查Javadocs中的信息。另一種情況,當你向ByteArrayOutputStream
中寫入時,緩衝不是必須的,因為你隻寫入內存。
最後更新:2017-05-19 14:33:23