NIO.2
JDK7對NIO進行了重大改進,主要包含以下兩方面
- 新增Path接口,Paths工具類,Files工具類。 這些接口和工具類對NIO中的功能進行了高度封裝,大大簡化了文件系統的IO編程。
- 基於異步Channel的IO
在NIO基礎上改進后的IO被稱為NIO.2 , 上面第一個改進包含在java.nio下新增的包java.nio.file包。 第二個改進包含在原有的java.nio.channels下,新增了多個Aysnchronous開頭的channel接口和類。
本文暫時只討論第一個改進,基於異步Channel的IO將在網絡通信中討論。
Path接口
在java.io及java.nio中,是通過File類來訪問文件系統(文件和目錄都用File類表示),但是File類不能利用特定文件系統的特性,且性能不高,拋出的異常也太抽象,因此在NIO.2中引入了Path接口。
Path接口表示的是一個與平台無關的路徑(文件和目錄都用Path表示)。
Path類中包含了常用的操作路徑的方法,
- getRoot() -Path對象的跟路徑
- toAbsolutePath() -Path對象的絕對路徑
- getNameCount() -Path對象里包含的路徑數量
Paths工具類
Paths工具類包含了兩個返回Path對象的靜態方法。
- static Path get(URI uri) 直接通過路徑返回Path對象
- static Path get(String first, String...more)通過給出的String字符串組裝成一個Path對象
下面演示Paths工具類和Path接口用法,
1 package nio; 2 3 import java.nio.file.Path; 4 import java.nio.file.Paths; 5 6 public class PathTest { 7 public static void main(String[] args) { 8 //在傳統java.io中, 文件和目錄都被抽象成File對象, 即 File file = new File("."); 9 //NIO.2中則引入接口Path代表與平台無關的路徑,文件和目錄都用Path對象表示 10 //通過路徑工具類Paths返回一個路徑對象Path 11 Path path = Paths.get("."); 12 System.out.println("path里包含的路徑數量:" + path.getNameCount()); 13 System.out.println("path的根路徑: "+path.getRoot()); 14 //path的絕對路徑 15 //對比傳統java.io, 取絕對路徑 file.getAbsoluteFile() 16 Path absolutePath = path.toAbsolutePath(); 17 System.out.println("path的絕對路徑:"); 18 System.out.println(absolutePath); 19 System.out.println("absolutePath的根路徑: "+absolutePath.getRoot()); 20 System.out.println("absolutePath里包含的路徑數量:" + absolutePath.getNameCount()); 21 System.out.println(absolutePath.getName(3)); 22 //以多個String來構建path 23 Path path2 = Paths.get("g:", "publish" , "codes"); 24 System.out.println(path2); 25 26 27 28 } 29 }
輸出如下,
1 path里包含的路徑數量:1 2 path的根路徑: null 3 path的絕對路徑: 4 C:\UsersADMIN\PROJECT\CrazyJAVA\PROJECT_JavaBasic\. 5 absolutePath的根路徑: C:\ 6 absolutePath里包含的路徑數量:6 7 CrazyJAVA 8 g:\publish\codes
Files工具類
Files是一個操作文件的工具類,包含了大量靜態方法,對舊的IO常用的功能進行了高度封裝,例如copty, readAllLines, write, 等等。
在舊的IO中的操作文件的類是File,但是File類只能操作文件(創建,刪除,修改屬性等),但是不能修改文件的內容。
但是Files工具類可以直接寫文件。
File工具類通常需要結合Path對象來使用。 常用方法,
copy(...) 拷貝文件,有3個重載方法,通常需要跟Path結合使用
- 操作文件
createDirectory(...) 創建目錄
createFile(...) 創建文件
delete(Path path) 刪除文件
...
- 判斷屬性
isHidden(Path path)
isReadable(Path path)
isDirectory(...)
...
- 讀寫文件
lines(Path path) 使用默認編碼讀文件所有行進數組
readAlllines(path ,cs ) 使用指定編碼讀所有行到數組
write(...) 寫文件,可以批量將數組中的數據寫入文件,也可以指定編碼
walkFileTree() 遍歷路徑
...
下面演示 Files的用法,
1 package nio; 2 3 import java.io.FileNotFoundException; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.nio.charset.Charset; 7 import java.nio.file.Files; 8 import java.nio.file.Paths; 9 import java.util.ArrayList; 10 import java.util.List; 11 12 //Files工具類通常結合Path對象使用 13 public class FileTest { 14 public static void main(String[] args) throws FileNotFoundException, IOException { 15 //將傳統io讀寫文件高度封裝之后,在NIO.2中拷貝文件只需要調用File工具類的copy()方法 16 Files.copy(Paths.get("tmp.txt"), new FileOutputStream("tmp2.txt")); 17 //是否為隱藏文件 18 System.out.println("tmp.txt是否為隱藏文件: "+Files.isHidden(Paths.get("tmp.txt"))); 19 //一次性讀取所有行 , 需要指定編碼規則 20 List<String> lines = Files.readAllLines(Paths.get("tmp.txt"), Charset.forName("gbk")); 21 System.out.println(lines); 22 //文件大小 23 System.out.println("tmp.txt文件大小為: "+Files.size(Paths.get("tmp.txt"))); 24 List<String> poem = new ArrayList<>(); 25 poem.add("海闊憑魚躍"); 26 poem.add("天高任鳥飛"); 27 //直接將字符串數組寫入文件 28 Files.write(Paths.get("tmp.txt"), poem, Charset.forName("gbk")); 29 } 30 }
輸出結果,
1 tmp.txt是否為隱藏文件: false 2 [海闊憑魚躍, 天高任鳥飛] 3 tmp.txt文件大小為: 24