20250226 工作隨筆 C#文件拷貝

发布于:2025-03-01 ⋅ 阅读:(91) ⋅ 点赞:(0)
 public bool CopyFileToDestination(DbConnect db, string sourceFilePath, Enums.OutputKubun outputKubun, int detailId = 3)
 {
     // 1.元のパスが存在しない場合はロールバックして終了
     if (string.IsNullOrWhiteSpace(sourceFilePath) || !File.Exists(sourceFilePath))
     {
         db.Rollback();
         return false;
     }

     // 2.対象となる出力フォルダー情報をデータベースから取得
     DataTable fileTable = ExportFileModel.SQL.Get(db, (int)outputKubun, detailId);
     string? destinationDirectory = fileTable.Rows.Count > 0 ? Convert.ToString(fileTable.Rows[0]["output_path"]) : string.Empty;

     // 3.ターゲットフォルダのパスが空/空白の場合ロールバックして終了
     if (string.IsNullOrWhiteSpace(destinationDirectory))
     {
         db.Rollback();
         return false;
     }

     // 4.ターゲットフォルダの物理存在を検証(存在しない場合ロールバックして終了)
     if (!Directory.Exists(destinationDirectory))
     {
         db.Rollback();
         return false;
     }

     // 5.完全な目的地ファイルパスを生成
     string destinationPath = Path.Combine(destinationDirectory, Path.GetFileName(sourceFilePath));

     // 6.ファイルを目的地にコピー(既存の場合は上書き)
     File.Copy(sourceFilePath, destinationPath, true);

     return true;
 }

 

🔍 代碼解析:CopyFileToDestination 方法

這個方法的功能是將 CSV 文件從 sourceFilePath 拷貝到數據庫指定的 output_path 目錄下,並根據不同條件進行校驗與回滾。方法的返回值是 bool,表示操作是否成功。


📌 方法簽名

public bool CopyFileToDestination(DbConnect db, string sourceFilePath, Enums.OutputKubun outputKubun, int detailId = 3)
  • db:數據庫連接對象, 用於查詢目標文件夾路徑,並在異常情況下進行回滾。
  • sourceFilePath:要複製的源 CSV 文件的完整路徑。
  • outputKubun:輸出類別的枚舉,用於查詢數據庫的 output_path
  • detailId:默認值為 3,用於查詢時的參數。

📌 代碼詳解(含中文註釋)

// 1. 如果源文件路徑為空或該文件不存在,則回滾事務並返回 false
if (string.IsNullOrWhiteSpace(sourceFilePath) || !File.Exists(sourceFilePath))
{
    db.Rollback();
    return false;
}

目的

  • 確保 sourceFilePath 非空(防止空參數)。
  • 確保文件存在(避免無效路徑拷貝)。
  • 如果條件不滿足,則回滾數據庫並返回 false

// 2. 從數據庫查詢對應的輸出文件夾路徑
DataTable fileTable = ExportFileModel.SQL.Get(db, (int)outputKubun, detailId);
string? destinationDirectory = fileTable.Rows.Count > 0 ? Convert.ToString(fileTable.Rows[0]["output_path"]) : string.Empty;

目的

  • 從數據庫查詢 output_path,即目標文件夾的路徑。
  • fileTable 中有數據,則從第一行獲取 output_path,否則返回 string.Empty(空字符串)。

// 3. 如果目標文件夾路徑為空或全是空格,則回滾事務並返回 false
if (string.IsNullOrWhiteSpace(destinationDirectory))
{
    db.Rollback();
    return false;
}

目的

  • 確保 output_path 有效(不能是空字符串、空白字符或 null)。
  • 若無效,則回滾數據庫並返回 false

// 4. 確保目標文件夾物理存在,如果不存在則回滾並返回 false
if (!Directory.Exists(destinationDirectory))
{
    db.Rollback();
    return false;
}

目的

  • 確保數據庫返回的 output_path 對應的文件夾真實存在
  • ❌ 缺點:這裡的處理方式是若目錄不存在則直接返回 false,但更好的做法是創建該目錄(見後續優化)。

// 5. 生成完整的目標文件路徑,確保文件名稱不變
string destinationPath = Path.Combine(destinationDirectory, Path.GetFileName(sourceFilePath));

目的

  • 獲取原始文件名:使用 Path.GetFileName(sourceFilePath) 確保不會改變文件名。
  • 拼接目標路徑Path.Combine(destinationDirectory, 原文件名) 得到完整的目標文件路徑。

// 6. 執行文件拷貝(如果目標文件已存在,則覆蓋)
File.Copy(sourceFilePath, destinationPath, true);

目的

  • 將源 CSV 文件拷貝到 destinationDirectory 目錄下
  • true 參數表示 如果目標文件已經存在,則覆蓋

return true;

目的

  • 文件成功拷貝後返回 true,表示操作成功

🔹 存在的問題

  1. 目標文件夾不存在時,應自動創建,而不是直接回滾
    • Directory.Exists(destinationDirectory) 檢查文件夾時,當文件夾不存在應該 CreateDirectory(destinationDirectory),而不是直接 return false
  2. 異常處理不足
    • File.Copy() 可能會拋異常(例如無權限),應該用 try-catch 捕獲異常並記錄錯誤日誌。

✅ 優化後的版本

public bool CopyFileToDestination(DbConnect db, string sourceFilePath, Enums.OutputKubun outputKubun, int detailId = 3)
{
    // 1. 檢查源文件是否有效
    if (string.IsNullOrWhiteSpace(sourceFilePath) || !File.Exists(sourceFilePath))
    {
        Console.WriteLine("源文件不存在或路徑無效:" + sourceFilePath);
        db.Rollback();
        return false;
    }

    // 2. 從數據庫獲取目標文件夾路徑
    DataTable fileTable = ExportFileModel.SQL.Get(db, (int)outputKubun, detailId);
    string? destinationDirectory = fileTable.Rows.Count > 0 ? Convert.ToString(fileTable.Rows[0]["output_path"]) : string.Empty;

    // 3. 確保目標文件夾有效
    if (string.IsNullOrWhiteSpace(destinationDirectory))
    {
        Console.WriteLine("數據庫返回的目標文件夾路徑無效");
        db.Rollback();
        return false;
    }

    try
    {
        // 4. 確保目標文件夾存在,如果不存在則創建
        Directory.CreateDirectory(destinationDirectory);

        // 5. 獲取目標文件的完整路徑
        string destinationPath = Path.Combine(destinationDirectory, Path.GetFileName(sourceFilePath));

        // 6. 執行文件拷貝(如果已存在則覆蓋)
        File.Copy(sourceFilePath, destinationPath, true);
    }
    catch (Exception ex)
    {
        Console.WriteLine("文件拷貝失敗:" + ex.Message);
        db.Rollback();
        return false;
    }

    return true;
}

🔹 優化點

  1. 自動創建目標文件夾

    • Directory.CreateDirectory(destinationDirectory) 如果文件夾已存在,不會拋異常,不存在時則會自動創建,避免了 if (!Directory.Exists(...)) 的判斷。
  2. 增加 Console.WriteLine,方便調試

    • 提供更詳細的錯誤信息,例如 源文件不存在、數據庫目錄無效、文件拷貝失敗等
  3. 使用 try-catch 捕獲異常

    • 避免 File.Copy() 失敗時直接崩潰(如無權限、目標文件夾被占用等)。
    • 發生異常時,記錄錯誤並回滾數據庫。

🚀 總結

版本 問題點 優化點
原始版本 目標文件夾不存在時直接 return false 自動創建目標文件夾
沒有異常處理 增加 try-catch 來避免程序崩潰
缺少錯誤信息輸出 Console.WriteLine() 輸出錯誤原因

這樣,新的 CopyFileToDestination 方法在安全性、健壯性、可讀性方面都有了明顯提升 🎯。

🔍 代碼解析:CopyFileToDestination 方法

這個方法的功能是將 CSV 文件從 sourceFilePath 拷貝到數據庫指定的 output_path 目錄下,並根據不同條件進行校驗與回滾。方法的返回值是 bool,表示操作是否成功。


📌 方法簽名

public bool CopyFileToDestination(DbConnect db, string sourceFilePath, Enums.OutputKubun outputKubun, int detailId = 3)
  • db:數據庫連接對象, 用於查詢目標文件夾路徑,並在異常情況下進行回滾。
  • sourceFilePath:要複製的源 CSV 文件的完整路徑。
  • outputKubun:輸出類別的枚舉,用於查詢數據庫的 output_path
  • detailId:默認值為 3,用於查詢時的參數。

📌 代碼詳解(含中文註釋)

// 1. 如果源文件路徑為空或該文件不存在,則回滾事務並返回 false
if (string.IsNullOrWhiteSpace(sourceFilePath) || !File.Exists(sourceFilePath))
{
    db.Rollback();
    return false;
}

目的

  • 確保 sourceFilePath 非空(防止空參數)。
  • 確保文件存在(避免無效路徑拷貝)。
  • 如果條件不滿足,則回滾數據庫並返回 false

// 2. 從數據庫查詢對應的輸出文件夾路徑
DataTable fileTable = ExportFileModel.SQL.Get(db, (int)outputKubun, detailId);
string? destinationDirectory = fileTable.Rows.Count > 0 ? Convert.ToString(fileTable.Rows[0]["output_path"]) : string.Empty;

目的

  • 從數據庫查詢 output_path,即目標文件夾的路徑。
  • fileTable 中有數據,則從第一行獲取 output_path,否則返回 string.Empty(空字符串)。

// 3. 如果目標文件夾路徑為空或全是空格,則回滾事務並返回 false
if (string.IsNullOrWhiteSpace(destinationDirectory))
{
    db.Rollback();
    return false;
}

目的

  • 確保 output_path 有效(不能是空字符串、空白字符或 null)。
  • 若無效,則回滾數據庫並返回 false

// 4. 確保目標文件夾物理存在,如果不存在則回滾並返回 false
if (!Directory.Exists(destinationDirectory))
{
    db.Rollback();
    return false;
}

目的

  • 確保數據庫返回的 output_path 對應的文件夾真實存在
  • ❌ 缺點:這裡的處理方式是若目錄不存在則直接返回 false,但更好的做法是創建該目錄(見後續優化)。

// 5. 生成完整的目標文件路徑,確保文件名稱不變
string destinationPath = Path.Combine(destinationDirectory, Path.GetFileName(sourceFilePath));

目的

  • 獲取原始文件名:使用 Path.GetFileName(sourceFilePath) 確保不會改變文件名。
  • 拼接目標路徑Path.Combine(destinationDirectory, 原文件名) 得到完整的目標文件路徑。

// 6. 執行文件拷貝(如果目標文件已存在,則覆蓋)
File.Copy(sourceFilePath, destinationPath, true);

目的

  • 將源 CSV 文件拷貝到 destinationDirectory 目錄下
  • true 參數表示 如果目標文件已經存在,則覆蓋

return true;

目的

  • 文件成功拷貝後返回 true,表示操作成功

🔹 存在的問題

  1. 目標文件夾不存在時,應自動創建,而不是直接回滾
    • Directory.Exists(destinationDirectory) 檢查文件夾時,當文件夾不存在應該 CreateDirectory(destinationDirectory),而不是直接 return false
  2. 異常處理不足
    • File.Copy() 可能會拋異常(例如無權限),應該用 try-catch 捕獲異常並記錄錯誤日誌。

✅ 優化後的版本

public bool CopyFileToDestination(DbConnect db, string sourceFilePath, Enums.OutputKubun outputKubun, int detailId = 3)
{
    // 1. 檢查源文件是否有效
    if (string.IsNullOrWhiteSpace(sourceFilePath) || !File.Exists(sourceFilePath))
    {
        Console.WriteLine("源文件不存在或路徑無效:" + sourceFilePath);
        db.Rollback();
        return false;
    }

    // 2. 從數據庫獲取目標文件夾路徑
    DataTable fileTable = ExportFileModel.SQL.Get(db, (int)outputKubun, detailId);
    string? destinationDirectory = fileTable.Rows.Count > 0 ? Convert.ToString(fileTable.Rows[0]["output_path"]) : string.Empty;

    // 3. 確保目標文件夾有效
    if (string.IsNullOrWhiteSpace(destinationDirectory))
    {
        Console.WriteLine("數據庫返回的目標文件夾路徑無效");
        db.Rollback();
        return false;
    }

    try
    {
        // 4. 確保目標文件夾存在,如果不存在則創建
        Directory.CreateDirectory(destinationDirectory);

        // 5. 獲取目標文件的完整路徑
        string destinationPath = Path.Combine(destinationDirectory, Path.GetFileName(sourceFilePath));

        // 6. 執行文件拷貝(如果已存在則覆蓋)
        File.Copy(sourceFilePath, destinationPath, true);
    }
    catch (Exception ex)
    {
        Console.WriteLine("文件拷貝失敗:" + ex.Message);
        db.Rollback();
        return false;
    }

    return true;
}

🔹 優化點

  1. 自動創建目標文件夾

    • Directory.CreateDirectory(destinationDirectory) 如果文件夾已存在,不會拋異常,不存在時則會自動創建,避免了 if (!Directory.Exists(...)) 的判斷。
  2. 增加 Console.WriteLine,方便調試

    • 提供更詳細的錯誤信息,例如 源文件不存在、數據庫目錄無效、文件拷貝失敗等
  3. 使用 try-catch 捕獲異常

    • 避免 File.Copy() 失敗時直接崩潰(如無權限、目標文件夾被占用等)。
    • 發生異常時,記錄錯誤並回滾數據庫。

🚀 總結

版本 問題點 優化點
原始版本 目標文件夾不存在時直接 return false 自動創建目標文件夾
沒有異常處理 增加 try-catch 來避免程序崩潰
缺少錯誤信息輸出 Console.WriteLine() 輸出錯誤原因

這樣,新的 CopyFileToDestination 方法在安全性、健壯性、可讀性方面都有了明顯提升 🎯。


网站公告

今日签到

点亮在社区的每一天
去签到