Java 文件 – java.nio.file.Files 类

Java Files类是在Java 1.7中引入的,属于java.nio.file包的一部分。

Java Files类

  • Java Files类包含static方法,用于处理文件和目录。
  • 这个类用于执行基本的文件操作,如创建、读取、写入、复制和删除文件或目录。

在继续之前,让我们先了解以下术语:

  1. Path:这是一个接口,用于在Java NIO中处理文件或目录,替代了java.io.File类。
  2. Paths:此类包含一个静态方法,用于创建Path实例。

java.nio.file.Path 介面就像舊的 java.io.File 類別一樣。 Path 代表檔案的位置,當我們建立一個指向新檔案的 Path 時,實際的檔案並不會被建立,直到我們使用 Files.createFile(Path filePath) 建立它。正如我們在上圖中所看到的,Paths 類別用於創建 Path 的實例,而 Files 類別則使用 Path 實例來操作檔案。FilePath 物件知道如何轉換成另一個,這就是我們可以使用舊的程式碼與新的 Files 工具進行互動的方式。

Java IO vs NIO

如何建立 Path

我們可以通過調用 Paths 類的 Paths.get(String first, String... more) 方法來創建 Path 物件。

Path path1 = Paths.get("/tmp/file.txt"); // For UNIX

Path path2 = Paths.get("D:/data/file.txt"); // For Windows

我們也可以通過在 Paths.get() 方法中分離路徑的各部分來創建 Path 物件。

Path path1 = Paths.get("/tmp", "file.txt");

Path path2 = Paths.get("D:", "data", "file.txt");

Path path3 = Paths.get("D:/data", "file.txt") ;

正如我們所看到的,我們可以分別在 Paths.get() 方法中傳遞資料夾和檔案名稱。

Java 檔案方法

Java NIO Files 類包含靜態方法,用於操作文件和目錄,這些方法大多作用於 Path 對象。讓我們看一下 Files 類的以下方法:

  1. copy(InputStream in, Path target, CopyOption… options): 此方法將指定的輸入流中的所有字節複製到指定的目標文件中,並將讀取或寫入的字節數作為長整型值返回。
  2. copy(Path source, OutputStream out): 此方法將指定源文件中的所有字節複製到給定的輸出流中,並將讀取或寫入的字節數作為長整型值返回。
  3. copy(Path source, Path target, CopyOption… options): 此方法將給定的源文件複製到指定的目標文件中,並返回目標文件的路徑。
  4. createDirectories(Path dir, FileAttribute<?>… attrs): 此方法通過首先創建所有不存在的父目錄來使用給定路徑創建目錄。如果無法創建目錄,因為它已經存在,則此方法不會引發異常。FileAttribute 是一個可選參數,在創建不存在的目錄時自動設置,並返回創建的目錄的路徑。
  5. createDirectory(Path dir, FileAttribute<?>… attrs): 此方法使用給定的路徑創建目錄,如果成功創建目錄,則返回創建的目錄路徑。如果目錄已存在,則會拋出 nio.file.FileAlreadyExistsException。
  6. createFile(Path path, FileAttribute<?>… attrs): 此方法使用給定的路徑創建一個新的空文件,並返回新創建的文件路徑(如果成功創建)。如果文件已存在,則會拋出 nio.file.FileAlreadyExistsException。
  7. createTempDirectory(Path dir, String prefix, FileAttribute<?>… attrs): 此方法使用給定的路徑創建一個臨時目錄,並使用給定的前綴生成目錄名稱。它將返回新創建的臨時目錄的路徑。
  8. createTempDirectory(String prefix, FileAttribute<?>… attrs): 此方法在默認的臨時文件目錄中創建一個臨時目錄,並使用給定的前綴生成目錄名稱。它將返回與默認文件系統關聯的新創建的臨時目錄的路徑。
  9. createTempFile(Path dir, String prefix, String suffix, FileAttribute<?>… attrs): 此方法在指定目錄中創建一個臨時文件,並使用給定的前綴和後綴生成文件名,然後返回新創建文件的路徑。
  10. createTempFile(String prefix, String suffix, FileAttribute<?>… attrs): 此方法在默認臨時文件目錄中創建臨時文件,並使用給定的前綴和後綴生成文件名,返回新創建文件的路徑。
  11. delete(Path path): 這是一個無返回值的方法,只是從指定路徑刪除文件。如果文件不存在於指定路徑,則此方法會拋出NoSuchFileException;如果文件是目錄且可能不為空且無法刪除,則會拋出
  12. deleteIfExists(Path path): 此方法在刪除文件之前檢查文件是否存在,並在給定路徑的文件成功刪除時返回布爾值 true,如果文件不存在於給定路徑則返回 false。如果文件是目錄且可能不為空且無法刪除,則會拋出
  13. exists(Path path): 此方法檢查指定路徑是否存在文件,如果文件存在則返回 true,否則返回 false。
  14. getLastModifiedTime(Path path, Linkoption… options): 此方法從給定路徑返回文件的最後修改時間作為
  15. getOwner(Path path, Linkoption… options): 此方法返回表示給定路徑的文件所有者的UserPrincipal
  16. isDirectory(Path path, LinkOption… options): 此方法檢查給定路徑的文件是否為目錄。如果文件是目錄,則返回true;如果文件不存在、不是目錄,或無法確定文件是否為目錄,則返回false。
  17. isExecutable(Path path): 此方法檢查給定路徑的文件是否可執行,同時檢查文件是否存在,以及此JVM是否具有執行文件的適當權限。如果文件在給定路徑存在且可執行,則返回true;如果文件不存在、JVM權限不足以執行文件,或者無法確定訪問權限,則返回false。
  18. isHidden(Path path): 此方法判斷給定路徑的文件是否被視為隱藏。隱藏的確切定義取決於平台或提供者。在UNIX系統中,如果文件名以句點字符(’。’)開頭,則該文件被視為隱藏;在WINDOWS中,如果文件不是目錄且設置了DOS隱藏屬性,則該文件被視為隱藏。如果在給定路徑的文件被視為隱藏,則返回true;否則返回false。
  19. isReadable(Path path): 此方法測試給定路徑的文件是否可讀。如果指定路徑的文件存在且可讀,則返回true;如果文件不存在、JVM因權限不足而拒絕讀取訪問,或者無法確定訪問權限,則返回false。
  20. isWritable(Path path): 此方法用于测试给定路径的文件是否可写。如果指定路径上的文件存在且可写,则返回true;如果文件不存在,或因JVM权限不足或无法确定访问权限而导致写访问被拒绝,则返回false。
  21. move(Path source, Path target, CopyOption… options): 此方法将源文件移动或重命名为目标文件,并返回目标文件的路径。选项参数可以包括以下内容:REPLACE_EXISTING: 如果目标文件存在,则替换它,但前提是它不是非空目录。ATOMIC_MOVE: 表示移动操作作为原子文件系统操作执行,所有其他选项将被忽略。如果目标文件存在但无法替换,因为未指定REPLACE_EXISTING选项,则此方法抛出FileAleadyExistsException。如果指定了REPLACE_EXISTING选项但文件无法替换,因为它是非空目录,则此方法抛出DirectoryNotEmptyException
  22. newBufferedReader(Path path, Charset cs): 此方法使用给定的路径打开文件以供读取,返回一个BufferedReader,用于从文件中读取文本。文件中的字节将使用指定的字符集解码为字符。
  23. newBufferedWriter(Path path, Charset cs, Openoption… options): 此方法打開或創建一個文件,使用給定的路徑進行寫入,並返回 BufferedWriter,該 BufferedWriter 用於向文件寫入文本。選項參數指定文件的創建或打開方式。如果未指定任何選項,則默認為CREATE、TRUNCATE_EXISTINGWRITE選項,這意味著它打開文件進行寫入,如果文件不存在則創建新文件,如果文件存在則截斷文件大小為 0。如果指定了不支持的選項,則此方法將拋出UnsupportedOperationException
  24. newByteChannel(Path path, OpenOption… options): 此方法通過返回一個可查詢的字節通道來創建或打開指定路徑的文件。如果指定了不支持的選項,則此方法將拋出UnsupportedOperationException
  25. newDirectoryStream(Path path): 此方法通過返回一個 DirectoryStream 打開一個目錄,以便迭代指定路徑中目錄中的所有條目。DirectoryStream 的迭代器返回的元素類型為 Path,每個元素代表目錄中的一個條目。如果無法打開給定路徑的文件,因為它不是目錄,則此方法將拋出NotDirectoryException
  26. newDirectoryStream(Path path, Filter<? super Path > filter): 此方法通過返回 DirectoryStream 來打開目錄,以便從指定的路徑迭代遍歷目錄中的所有條目。DirectoryStream 迭代器返回的元素是 Path 類型的,每個 Path 代表目錄中的一個條目,這些條目由指定的過濾器進行篩選。如果給定路徑的文件無法打開,因為它不是目錄,則此方法會拋出 NotDirectoryException
  27. newDirectoryStream(Path path, String glob): 此方法通過返回 DirectoryStream 來打開目錄,以便從指定的路徑迭代遍歷目錄中的所有條目。DirectoryStream 迭代器返回的元素是 Path 類型的,每個 Path 代表目錄中的一個條目,這些條目通過與指定的 glob 模式匹配的它們的文件名的字符串表示進行篩選。如果給定路徑的文件無法打開,因為它不是目錄,則此方法會拋出 NotDirectoryException,如果模式無效則拋出 PatternSyntaxException
  28. newInputStream(Path path, Openoption… options): 此方法通過返回輸入流來打開文件,以從指定的路徑讀取文件。options 參數決定了文件的打開方式,如果未指定任何選項,則使用 READ 選項打開文件。如果指定了無效的選項組合,則此方法會拋出 IllegalArgumentException,如果指定了不支持的選項,則拋出 UnsupportedOperationException
  29. newOutputStream(Path path, Openoption… options): 此方法通過返回輸出流以寫入字節到指定路徑的文件來打開文件。選項參數確定了文件如何被打開,如果未指定選項,則默認考慮CREATE、TRUNCATE_EXISTINGWRITE選項,這意味著它打開文件進行寫入,並且如果文件不存在則創建,如果存在則截斷現有文件為大小為0。如果指定了無效的選項組合,則此方法會拋出IllegalArgumentException,如果指定了不支持的選項,則會拋出UnsupportedOperationException
  30. notExists(Path path, LinkOption options): 此方法測試指定路徑的文件是否不存在。選項參數用於指示如果文件是符號鏈接時如何處理符號鏈接。默認情況下,將跟隨符號鏈接。如果存在選項NOFOLLOW_LINK,則不會跟隨符號鏈接。如果文件在指定路徑不存在,則此方法返回true,如果文件存在或者無法確定其存在性,則返回false。
  31. readAllBytes(Path path): 此方法從給定路徑的文件讀取所有字節並返回包含從文件讀取的字節的字节数組。
  32. readAllLines(Path path, Charset cs): 此方法從給定路徑的文件讀取所有行並返回包含文件中行的List
  33. size(Path path): 此方法返回指定路径处文件的大小(以字节为单位)。
  34. walkFileTree(Path start, FileVisitor<? Super Path> visitor): 此方法用于遍历目录。它递归地遍历指定路径处的目录,并返回起始文件。
  35. write(Path path, byte[] bytes, OpenOption… options): 此方法将字节写入到指定路径处的文件中。options 参数指定如何创建或打开文件。如果未指定任何选项,则默认考虑 CREATE、TRUNCATE_EXISTING 和 WRITE 选项,这意味着它会打开文件进行写入,并在文件不存在时创建文件,或者在文件存在时截断现有文件至大小为 0。将字节数组中的所有字节写入文件。此方法确保在写入所有字节后关闭文件,并返回写入文件的路径。

使用 Files 类创建文件

Files 类提供了 createFile(Path filePath, FileAttribute<?>… attrs) 方法,用于使用指定的 Path 创建文件。让我们看一下下面的示例程序。

package com.journaldev.examples;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * Java Create file using Files class
 * 
 * @author pankaj
 *
 */
public class FilesCreateFileExample {

	public static void main(String[] args) {
		
		//初始化 Path 对象
		Path path = Paths.get("D:/data/file.txt");
		//创建文件
		try {
			Path createdFilePath = Files.createFile(path);
			System.out.println("File Created at Path : "+createdFilePath);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

以上程序的输出如下:

File Created at Path : D:\data\file.txt

使用 Files 類創建目錄

Files 類提供 createDirectory(Path dir, FileAttribute<?>… attrs)createDirectories(Path dir, FileAttribute<?>… attrs) 方法來使用指定的 Path 創建單個和多級目錄。讓我們看一下下面的示例程序。

package com.journaldev.examples;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * Java Create directories using Files class
 * 
 * @author pankaj
 *
 */
public class FilesCreateDirectoriesExample {

	public static void main(String[] args) {
		// 初始化 Path 對象
		Path path1 = Paths.get("D:/pankaj");
		Path path2 = Paths.get("D:/pankaj/java7");
		Path path3 = Paths.get("D:/pankaj/java7/Files");
		
		try {
			Path createdDir1 = Files.createDirectory(path1);//first level directory
			Path createdDir2 = Files.createDirectory(path2);//second level directory
			Path createdDir3 = Files.createDirectory(path3);//all level directories
			System.out.println("First Level Directory Created at Path : "+createdDir1);
			System.out.println("Second Level Directory Created at Path : "+createdDir2);
			System.out.println("All Level Directories Created at Path : "+createdDir3);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

上面程序的輸出如下:

First Level Directory Created at Path : D:\pankaj
Second Level Directory Created at Path : D:\pankaj\java7
All Level Directories Created at Path : D:\pankaj\java7\Files

將文件轉換為路徑及其反之

可以使用以下方法將文件和路徑對象互相轉換:

File file = new File(“D:/data/file.txt”);

Path path = file.toPath();

File file1 = path.toFile();

使用 Files 類讀取文件數據

Files 類提供了以下方法來讀取文件。

  1. readAllBytes(Path path): 此方法從給定路徑的文件中讀取所有字節,並返回包含從文件中讀取的字節的字節數組。
  2. readAllLines(Path path, Charsetcs):此方法從給定路徑讀取文件的所有行,並返回包含文件行的List

讓我們看下面的示例程序。

package com.journaldev.examples;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

/**
 * Java Files read file example
 * 
 * @author pankaj
 *
 */
public class FilesReadFileExample {

	public static void main(String[] args) {
		
		Path path = Paths.get("D:/data/file.txt");
		try {
			byte[] bs = Files.readAllBytes(path);
			List<String> strings = Files.readAllLines(path);
			
			System.out.println("Read bytes: \n"+new String(bs));
			System.out.println("Read lines: \n"+strings);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

上述程序的輸出如下:

Read bytes: 
Hello world
This is Read file example
Thank you
Read lines: 
[Hello world, This is Read file example, Thank you]

使用Files類複製文件

Files類提供copy(Path source, Path target, CopyOption… options)方法,將給定的源文件複製到指定的目標文件,並返回目標文件的路徑。讓我們看下面的示例程序:

package com.journaldev.examples;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

/**
 * Java Files copy file example
 * 
 * @author pankaj
 *
 */
public class FilesCopyFileExample {

	public static void main(String[] args) {
		Path sourcePath = Paths.get("D:/data/sourceFile.txt");
		Path targetPath = Paths.get("D:/data/targetFile.txt");
		
		try {
			Path path = Files.copy(sourcePath, targetPath,StandardCopyOption.REPLACE_EXISTING);//copy with REPLACE_EXISTING option
			System.out.println("Target file Path : "+path);
			System.out.println("Copied Content : \n"+new String(Files.readAllBytes(path)));
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

上述程序的輸出如下:

Target file Path : D:\data\targetFile.txt
Copied Content : 
Hello world
This is Copy file example
Thank you

使用Files類移動文件

Java Files 類別提供了 move(Path source, Path target, CopyOption… options) 方法,用於將源文件移動或重命名為目標文件並返回目標文件的路徑。選項參數可能包括以下內容:REPLACE_EXISTING: 如果目標文件存在,則替換它,如果它不是非空目錄。 ATOMIC_MOVE: 表示移動作為原子文件系統操作執行,並且所有其他選項將被忽略。如果目標文件存在但無法替換,因為未指定 REPLACE_EXISTING 選項,則此方法將拋出 FileAleadyExistsException。如果指定了 REPLACE_EXISTING 選項但無法替換文件,因為它是非空目錄,則此方法將拋出 DirectoryNotEmptyException。讓我們看一下下面的範例程序:

package com.journaldev.examples;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

/**
 * Java Files move file example
 * 
 * @author pankaj
 *
 */
public class FilesMoveFileExample {

	public static void main(String[] args) {
		Path sourcePath = Paths.get("D:/data/sourceFile.txt");
		Path targetPath = Paths.get("D:/data/targetFile.txt");
		try {
			Path path = Files.move(sourcePath, targetPath,StandardCopyOption.REPLACE_EXISTING);//move with REPLACE_EXISTING option
			System.out.println("Target file Path : "+path);
			System.out.println("Moved Content : \n"+new String(Files.readAllBytes(path)));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

使用 Files 類別寫文件

Java NIO Files 類別提供 write(Path path, byte[] bytes, OpenOption… options) 方法,用於將位元組寫入指定路徑的檔案。options 參數指定了檔案的建立或開啟方式。如果未指定任何選項,則預設為 CREATE, TRUNCATE_EXISTING 以及 WRITE 選項。這表示它以寫入模式開啟檔案,如果檔案不存在則創建,或者如果存在則截斷檔案大小為 0。所有位元組陣列中的位元組都將寫入檔案。該方法確保在所有位元組寫入後關閉檔案並返回寫入的檔案路徑。

package com.journaldev.examples;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * Java Files write file example
 * 
 * @author pankaj
 *
 */
public class FilesWriteFileExample {

	public static void main(String[] args) {
		Path path = Paths.get("D:/data/test.txt");
		try {
			String str = "This is write file Example";
			byte[] bs = str.getBytes();
			Path writtenFilePath = Files.write(path, bs);
			System.out.println("Written content in file:\n"+ new String(Files.readAllBytes(writtenFilePath)));
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

Walk File Tree

Files 類別提供 walkFileTree(Path start, FileVisitor<? Super Path> visitor) 方法,用於遞歸地遍歷目錄。它遍歷指定路徑的目錄,並返回起始檔案。

package com.journaldev.examples;

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;

/**
 * Java Files walk file tree example
 * 
 * @author pankaj
 *
 */
public class FilesWalkFileTreeExample {

	public static void main(String[] args) {
		Path path = Paths.get("D:/pankaj");
		try {
			Files.walkFileTree(path, new FileVisitor<Path>() {

				@Override
				public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
					System.out.println("Post Visit Directory: "+dir);
					return FileVisitResult.CONTINUE;
				}

				@Override
				public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
					System.out.println("Pre Visit Directory: "+dir);
					return FileVisitResult.CONTINUE;
				}

				@Override
				public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
					System.out.println("Visit File: "+file);
					return FileVisitResult.CONTINUE;
				}

				@Override
				public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
					System.out.println("Visit Failed File: "+file);
					return FileVisitResult.CONTINUE;
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

上述程式的輸出如下:

Pre Visit Directory: D:\pankaj
Pre Visit Directory: D:\pankaj\java6
Pre Visit Directory: D:\pankaj\java6\Files
Visit File: D:\pankaj\java6\Files\file.txt.txt
Post Visit Directory: D:\pankaj\java6\Files
Post Visit Directory: D:\pankaj\java6
Pre Visit Directory: D:\pankaj\java7
Pre Visit Directory: D:\pankaj\java7\Files
Visit File: D:\pankaj\java7\Files\file.txt.txt
Post Visit Directory: D:\pankaj\java7\Files
Post Visit Directory: D:\pankaj\java7
Pre Visit Directory: D:\pankaj\java8
Pre Visit Directory: D:\pankaj\java8\Files
Visit File: D:\pankaj\java8\Files\file.txt.txt
Post Visit Directory: D:\pankaj\java8\Files
Post Visit Directory: D:\pankaj\java8
Post Visit Directory: D:\pankaj

請注意,所有檔案和資料夾都被遞歸處理。當您想要對目錄中的所有檔案執行一些通用處理(例如遞歸地重新命名目錄中的所有檔案)時,這非常有用。這就是 Java Files 類別的所有內容。參考:API 文件

Source:
https://www.digitalocean.com/community/tutorials/java-files-nio-files-class