1. 程式人生 > >NIO.2中的檔案與資源支援

NIO.2中的檔案與資源支援

隨著JDK 7 的釋出,Java對NIO進行了極大的擴充套件,增強了對檔案處理和檔案系統特性的支援,以至於我們稱他們為NIO.2。因為NIO 提供的一些功能,NIO已經成為檔案處理中越來越重要的部分。

【1】Path 與Paths

java.nio.file.Path 介面代表一個平臺無關的平臺路徑,描述了目錄結構中檔案的位置。

Paths 提供的get() 方法用來獲取Path 物件:

Path get(String first, String … more) : 用於將多個字串串連成路徑。

e.g:
FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);

Path常用方法:

方法 描述
boolean endsWith(String path) 判斷是否以path 路徑結束
boolean startsWith(String path) 判斷是否以path 路徑開始
boolean isAbsolute() 判斷是否是絕對路徑
Path getFileName() 返回與呼叫Path 物件關聯的檔名
Path getName(int idx) 返回的指定索引位置idx 的路徑名稱
int getNameCount() 返回Path 根目錄後面元素的數量
Path getParent() 返回Path物件包含整個路徑,不包含Path 物件指定的檔案路徑
Path getRoot() 返回呼叫Path 物件的根路徑
Path resolve(Path p) 將相對路徑解析為絕對路徑
Path toAbsolutePath() 作為絕對路徑返回呼叫Path 物件
String toString() 返回呼叫Path 物件的字串表示形式

測試例項一如下:

	@Test
	public void test1(){
		Path path = Paths.get("d:/", "nio/hello.txt");
		
		System.out.println(path.endsWith("hello.txt"));
		System.out.println(path.startsWith("e:/"));
		
		System.out.println(path.isAbsolute());
		System.out.println(path.getFileName());
		
		for (int i = 0; i < path.getNameCount(); i++) {
			System.out.println(path.getName(i));
		}
	}

測試結果如下:

true
false
true
hello.txt
nio
hello.txt

注意,並不會校驗"d:/nio/hello.txt"究竟是否存在!

測試例項二如下:

	@Test
	public void test2(){
		Path path = Paths.get("e:/nio/hello.txt");
		
		System.out.println(path.getParent());
		//e:\nio
		System.out.println(path.getRoot());
		//e:\
		
//		Path newPath = path.resolve("e:/hello.txt");
//		System.out.println(newPath);

		Path path2 = Paths.get("1.jpg");
		Path newPath = path2.toAbsolutePath();
		System.out.println(newPath);
		//D:\workspace_idea\hh-test\nio\1.jpg
		
		System.out.println(path.toString());
		//e:\nio\hello.txt
	}

【2】Files 類

java.nio.file.Files 用於操作檔案或目錄的工具類。

Files常用方法:

  • Path copy(Path src, Path dest, CopyOption … how) : 檔案的複製
  • PathcreateDirectory(Path path, FileAttribute<?> … attr) : 建立一個目錄
  • Path createFile(Path path, FileAttribute<?> … arr) : 建立一個檔案
  • void delete(Path path) : 刪除一個檔案
  • Path move(Path src, Path dest, CopyOption…how) : 將src 移動到dest 位置
  • long size(Path path) : 返回path 指定檔案的大小

檔案複製例項如下:

	@Test
	public void test3() throws IOException{
		Path path1 = Paths.get("e:/nio/hello.txt");
		Path path2 = Paths.get("e:/nio/hello2.txt");
		Files.copy(path1, path2, StandardCopyOption.REPLACE_EXISTING);
	}

建立刪除檔案例項如下:

	@Test
	public void test4() throws IOException{
		Path dir = Paths.get("e:/nio/nio2");
//		Files.createDirectory(dir);
		
		Path file = Paths.get("e:/nio/nio2/hello3.txt");
//		Files.createFile(file);
		
		Files.deleteIfExists(file);
	}

移動檔案/檢視檔案大小例項如下:

	@Test
	public void test5() throws IOException{
		Path path1 = Paths.get("e:/nio/hello2.txt");
		Path path2 = Paths.get("e:/nio/hello7.txt");
		
		System.out.println(Files.size(path2));
		
//		Files.move(path1, path2, StandardCopyOption.ATOMIC_MOVE);
	}

Files常用方法:用於判斷

  • boolean exists(Path path, LinkOption … opts) : 判斷檔案是否存在
  • boolean isDirectory(Path path, LinkOption … opts) : 判斷是否是目錄
  • boolean isExecutable(Path path) : 判斷是否是可執行檔案
  • boolean isHidden(Path path) : 判斷是否是隱藏檔案
  • boolean isReadable(Path path) : 判斷檔案是否可讀
  • boolean isWritable(Path path) : 判斷檔案是否可寫
  • boolean notExists(Path path, LinkOption … opts) : 判斷檔案是否不存在
  • public static <A extends BasicFileAttributes> A readAttributes(Path path,Class<A> type,LinkOption... options) : 獲取與path 指定的檔案相關聯的屬性。

例項如下:

	@Test
	public void test6() throws IOException{
		Path path = Paths.get("d:/nio/hello7.txt");
//		System.out.println(Files.exists(path, LinkOption.NOFOLLOW_LINKS));
		
		BasicFileAttributes readAttributes = Files.readAttributes(path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
		System.out.println(readAttributes.creationTime());
		System.out.println(readAttributes.lastModifiedTime());
		
		DosFileAttributeView fileAttributeView = Files.getFileAttributeView(path, DosFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
		
		fileAttributeView.setHidden(false);
	}

Files常用方法:用於操作內容

  • SeekableByteChannel newByteChannel(Path path, OpenOption…how) : 獲取與指定檔案的連線,how 指定開啟方式。
  • DirectoryStream newDirectoryStream(Path path) : 開啟path 指定的目錄
  • InputStream newInputStream(Path path, OpenOption…how):獲取InputStream 物件
  • OutputStream newOutputStream(Path path, OpenOption…how) : 獲取OutputStream 物件

測試例項如下:

	@Test
	public void test7() throws IOException{
		SeekableByteChannel newByteChannel = Files.newByteChannel(Paths.get("1.jpg"), StandardOpenOption.READ);
		
		DirectoryStream<Path> newDirectoryStream = Files.newDirectoryStream(Paths.get("d:/"));
		
		for (Path path : newDirectoryStream) {
			System.out.println(path);
		}
	}

【3】自動資源管理

Java 7 增加了一個新特性,該特性提供了另外一種管理資源的方式,這種方式能自動關閉檔案。這個特性有時被稱為自動資源管理(Automatic Resource Management, ARM),該特性以try 語句的擴充套件版為基礎。

自動資源管理主要用於,當不再需要檔案(或其他資源)時,可以防止無意中忘記釋放它們。

自動資源管理基於try 語句的擴充套件形式:

try(需要關閉的資源宣告){
	//可能發生異常的語句
}catch(異常型別變數名){
	//異常的處理語句
}finally{
	//一定執行的語句
}

當try 程式碼塊結束時,自動釋放資源。因此不需要顯示的呼叫close() 方法。該形式也稱為“帶資源的try 語句”。

注意:

①try 語句中宣告的資源被隱式宣告為final ,資源的作用侷限於帶資源的try 語句 ②可以在一條try 語句中管理多個資源,每個資源以“;” 隔開即可。 ③需要關閉的資源,必須實現了AutoCloseable 介面或其自介面Closeable

測試例項如下:

@Test
public void test8(){
	try(FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
		FileChannel outChannel = FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.WRITE, StandardOpenOption.CREATE)){
		
		ByteBuffer buf = ByteBuffer.allocate(1024);
		inChannel.read(buf);
		
	}catch(IOException e){
		e.printStackTrace();
	}
}