---
# System prepended metadata

title: File 檔案及文件處理
tags: [Java]

---

# File 檔案及文件處理

## 判斷若資料夾不存在則建立

```
public static boolean createDir(String dirPathStr) { 
    // 判斷路徑是否斜線結尾( File.separator 可在各作業系統通用)
    if (!dirPathStr.endsWith(File.separator)) {  
            dirPathStr = dirPathStr + File.separator;  
       }
    File dir = new File(dirPathStr); 
    // 若尚未創建資料夾則創建
    if (!dir.exists()) {
        // 創建動作本身自帶布林值，順便判斷是否成功
        if (dir.mkdirs()) {  
           System.out.println("创建目录" + destDirName + "成功！");  
           return true;  
           } else {  
           System.out.println("创建目录" + destDirName + "失败！ 請檢查權限等其他因素");  
           return false;  
        }
        }; 
    }  
```
[java如果目录不存在则创建目录](https://blog.csdn.net/weixin_39549656/article/details/79468115)

## 判斷檔案內容是否為空

length() 可以計算檔案內字節數

```
if(file.exists() && file.length() == 0) {  
    System.out.println("文件为空！");  
} 
```

[java判断一个txt文本是否为空](https://my.oschina.net/u/3197158/blog/1627964)

## 判斷一個文件檔案的行數

### 舊方法，比較快，計算換行符號所得

public static int getFileLineNum(String filePath) {
    try (LineNumberReader lineNumberReader = new LineNumberReader(new FileReader(filePath))){
        lineNumberReader.skip(Long.MAX_VALUE);
        int lineNumber = lineNumberReader.getLineNumber();
        //這邊假設末行沒有換行符號會少一個，實際上要檢查有多少換行符號，應該用小樣文本先丟到 nopad++ 裡檢查
        //在nopad++裡，下方介面的 lines 會採計算行符號，而左邊行數編號方便直接檢視有幾行實質資料
        return lineNumber + 1;
    } catch (IOException e) {
        return -1;
    }
}

### 新方法，比較潮

// 回傳一個 long 值，建議錯誤處理不用拋出直接設定回傳 -1 會比較好設計邏輯
Files.lines(Paths.get(filePath)).count();

[java高效获取大文件的行数](https://blog.csdn.net/xingbaozhen1210/article/details/88948810)


## 讀取大型文件檔案內容

可以注意到 reader 最後才關掉，代表 readline() 可能是全部先讀完才做事，如此的話這個方法相對不是那麼好，**在讀取巨量資料時可能 OOM**

```
URL url = new URL(fileurl);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
List<String> mobileList = new ArrayList<>();
String lineTxt = null;
while ((lineTxt = reader.readLine()) != null) {
    //檔案內容校驗：作手機號碼是否合法的字串判斷
    if (PhoneUtil.isMobileNO(lineTxt)) {
        mobileList.add(lineTxt);
       }
      }
reader.close();
```

[java分段读取txt文件？？](https://bbs.csdn.net/topics/392645821)

同樣的需求，用 LineIterator 會比較保險

// 設定一個計數器
int total = 0;
LineIterator lit = FileUtils.lineIterator(txtFile);
while (lit.hasNext()) {
    // 迭代器一定要先設定一個記憶體位置給它放，不然每 call 到一次 .next() 他都會往下跳一個
    String line = lit.next();
    // 指定首行你想做的事，後面記得將計數器++，下一輪才會做平常 routine 的工作
    if (total == 0) {
        total++;
        continue;
        }
// 除了首行外，其他每行要做的事寫在這
total++;
// 每 500 行要做什麼(例如執行某行 SQL 存到 DB 等)
if (total % 500 == 0) {
    pisInsertDetail.executeBatch();
    connXRE.commit();
    }
}
// 當迴圈跑完，仍有資料但不足 500 行時，會在這處理掉(例如一樣執行某行 SQL 存到 DB 等)
pisInsertDetail.executeBatch();
connXRE.commit();

###### tags: `Java`