### byte[] to File
```java
import org.apache.commons.io.IOUtils;
import java.io.FileOutputStream;
import java.io.IOException;
public class WriteByteArrayToFileExample {
public static void main(String[] args) {
byte[] byteArray = {65, 66, 67, 68, 69}; // Sample byte array
try {
FileOutputStream fos = new FileOutputStream("output.txt");
IOUtils.write(byteArray, fos);
fos.close();
System.out.println("Byte array has been written to file successfully.");
} catch (IOException e) {
System.err.println("Error writing byte array to file: " + e.getMessage());
}
}
}
```
在上面的範例中,我們將一個包含 ASCII 值的 byte array 寫入到一個檔案中,並使用 Apache Commons IO 的 IOUtils 來執行實際的寫入動作。如果成功寫入檔案,將會列印出 "Byte array has been written to file successfully.",如果有任何錯誤發生,將會列印出錯誤訊息。
# Paths
在 Java NIO 裡,`Paths.get(...)` 只是把你傳進去的字串「包成」一個 `Path` 物件,它本身並不會去打開檔案、也不會檢查許可權──真正存取(讀/寫/刪除)還是要靠 `Files` 這一類 API,或者呼叫 `Path.toFile()` 之後用傳統的 `File` API。
因此:
1. 你可以用 `Paths.get(...)` 產生任何字串形式合法的路徑(絕對、相對、包含 `..`、Windows 的 UNC 路徑…)
2. 只有當你用 `Files.readAllLines(path)`、`Files.newBufferedReader(path)`、`Files.delete(path)` … 等方法去操作時,才會觸發:
- OS 層級的「檔案是否存在」(不存在拋 `NoSuchFileException`)
- OS 層級的「權限檢查」(沒讀取權限拋 `AccessDeniedException`)
- 如果程式有啟用 Java SecurityManager,也可能被 `AccessControlException` 攔下
範例 1:任意路徑都可以包成 Path,但讀檔時才真正驗權限
```
import java.nio.file.*;
public class Demo {
public static void main(String[] args) throws Exception {
// 假設使用者輸入的路徑
String userInput = "/etc/passwd";
Path p = Paths.get(userInput);
// 下面這行如果程式執行帳號沒權限,就會拋 AccessDeniedException
// 或檔案不存在就拋 NoSuchFileException
for (String line : Files.readAllLines(p)) {
System.out.println(line);
}
}
}
```
範例 2:防止「路徑穿越」(Path Traversal)
如果你只想讓使用者存取某個基底資料夾(例如 `/home/app/data`)裡的檔案,就要在開檔前先把路徑正規化、並檢查不超出基底目錄:
```
import java.nio.file.*;
public class SafeDemo {
public static void main(String[] args) throws Exception {
String baseDir = "/home/app/data";
String userInput = "../etc/passwd"; // 惡意輸入
Path basePath = Paths.get(baseDir).toRealPath(); // 正規化、展開符號連結
Path target = basePath.resolve(userInput).normalize();
if (!target.startsWith(basePath)) {
throw new SecurityException("非法路徑存取:" + target);
}
// 通過檢查後再安心讀檔
Files.lines(target).forEach(System.out::println);
}
}
```
重點整理
- Paths.get(...) 本身「不會」限制你傳多高多深、多上層或多不同磁碟分割區,它只負責把字串轉成 `Path`。
- 真正的檔案存在性、讀寫刪除權限檢查是由後面呼叫 `Files`、`FileChannel`… 等 I/O API 時,跟底層作業系統互動時才會發生。
- 若你的程式有「只能訪問應用程式資料目錄」之類的安全需求,務必要自行做路徑正規化(`toRealPath()` + `normalize()`)並檢查 `startsWith(basePath)`。