這篇文章主要介紹了C#實現的檔案操作封裝類,結合完整執行個體形式分析了C#封裝檔案的刪除,移動,複製,重新命名等操作相關實現技巧,需要的朋友可以參考下
本文執行個體講述了C#實現的檔案操作封裝類。分享給大家供大家參考,具體如下:
最近發現群共用裡面有個C# 檔案操作封裝類,其方法是調用Windows API 來操作的檔案的刪除、移動、複製、重新命名操作。下載下來一試,發現果然不錯,特在此記錄,以防丟失!
檔案操作類代碼如下:
using System;using System.Runtime.InteropServices;using System.IO;namespace LxFile{ /// <summary> /// 檔案操作代理,該類提供類似於Windows的檔案操作體驗 /// </summary> public class FileOperateProxy { #region 【內部類型定義】 private struct SHFILEOPSTRUCT { public IntPtr hwnd; //父視窗控制代碼 public wFunc wFunc; //要執行的動作 public string pFrom; //源檔案路徑,可以是多個檔案,以結尾符號"\0"結束 public string pTo; //目標路徑,可以是路徑或檔案名稱 public FILEOP_FLAGS fFlags; //標誌,附加選項 public bool fAnyOperationsAborted; //是否可被中斷 public IntPtr hNameMappings; //檔案對應名字,可在其它 Shell 函數中使用 public string lpszProgressTitle; // 只在 FOF_SIMPLEPROGRESS 時,指定對話方塊的標題。 } private enum wFunc { FO_MOVE = 0x0001, //移動檔案 FO_COPY = 0x0002, //複製檔案 FO_DELETE = 0x0003, //刪除檔案,只是用pFrom FO_RENAME = 0x0004 //檔案重新命名 } private enum FILEOP_FLAGS { FOF_MULTIDESTFILES = 0x0001, //pTo 指定了多個目標檔案,而不是單個目錄 FOF_CONFIRMMOUSE = 0x0002, FOF_SILENT = 0x0044, // 不顯示一個進度對話方塊 FOF_RENAMEONCOLLISION = 0x0008, // 碰到有抵觸的名字時,自動分配首碼 FOF_NOCONFIRMATION = 0x10, // 不對使用者顯示提示 FOF_WANTMAPPINGHANDLE = 0x0020, // 填充 hNameMappings 欄位,必須使用 SHFreeNameMappings 釋放 FOF_ALLOWUNDO = 0x40, // 允許撤銷 FOF_FILESONLY = 0x0080, // 使用 *.* 時, 只對檔案操作 FOF_SIMPLEPROGRESS = 0x0100, // 簡單進度條,意味者不顯示檔案名稱。 FOF_NOCONFIRMMKDIR = 0x0200, // 建新目錄時不需要使用者確定 FOF_NOERRORUI = 0x0400, // 不顯示出錯使用者介面 FOF_NOCOPYSECURITYATTRIBS = 0x0800, // 不複製 NT 檔案的安全屬性 FOF_NORECURSION = 0x1000 // 不遞迴目錄 } #endregion 【內部類型定義】 #region 【DllImport】 [DllImport("shell32.dll")] private static extern int SHFileOperation(ref SHFILEOPSTRUCT lpFileOp); #endregion 【DllImport】 #region 【刪除檔案操作】 /// <summary> /// 刪除單個檔案。 /// </summary> /// <param name="fileName">刪除的檔案名稱</param> /// <param name="toRecycle">指示是將檔案清除還是永久刪除,true-清除,false-永久刪除</param> /// <param name="showDialog">指示是否顯示確認對話方塊,true-顯示確認刪除對話方塊,false-不顯示確認刪除對話方塊</param> /// <param name="showProgress">指示是否顯示進度對話方塊,true-顯示,false-不顯示。該參數當指定永久刪除檔案時有效</param> /// <param name="errorMsg">反饋錯誤訊息的字串</param> /// <returns>操作執行結果標識,刪除檔案成功返回0,否則,返回錯誤碼</returns> public static int DeleteFile(string fileName, bool toRecycle, bool showDialog, bool showProgress, ref string errorMsg) { try { string fName = GetFullName(fileName); return ToDelete(fName, toRecycle, showDialog, showProgress, ref errorMsg); } catch (Exception ex) { errorMsg = ex.Message; return -200; } } /// <summary> /// 刪除一組檔案。 /// </summary> /// <param name="fileNames">字串數組,表示一組檔案名稱</param> /// <param name="toRecycle">指示是將檔案清除還是永久刪除,true-清除,false-永久刪除</param> /// <param name="showDialog">指示是否顯示確認對話方塊,true-顯示確認刪除對話方塊,false-不顯示確認刪除對話方塊</param> /// <param name="showProgress">指示是否顯示進度對話方塊,true-顯示,false-不顯示。該參數當指定永久刪除檔案時有效</param> /// <param name="errorMsg">反饋錯誤訊息的字串</param> /// <returns>操作執行結果標識,刪除檔案成功返回0,否則,返回錯誤碼</returns> public static int DeleteFiles(string[] fileNames, bool toRecycle, bool showDialog, bool showProgress, ref string errorMsg) { try { string fName = ""; foreach (string str in fileNames) { fName += GetFullName(str) + "\0"; //組件檔案組字串 } return ToDelete(fName, toRecycle, showDialog, showProgress, ref errorMsg); } catch (Exception ex) { errorMsg = ex.Message; return -200; } } #endregion 【刪除檔案操作】 #region 【移動檔案操作】 /// <summary> /// 移動一個檔案到指定路徑下 /// </summary> /// <param name="sourceFileName">要移動的檔案名稱</param> /// <param name="destinationPath">移動到的目的路徑</param> /// <param name="showDialog">指示是否顯示確認對話方塊,true-顯示確認對話方塊,false-不顯示確認對話方塊</param> /// <param name="showProgress">指示是否顯示進度對話方塊</param> /// <param name="autoRename">指示當檔案名稱重複時,是否自動為新檔案加上尾碼名</param> /// <param name="errorMsg">反饋錯誤訊息的字串</param> /// <returns>返回移動操作是否成功的標識,成功返回0,失敗返回錯誤碼</returns> public static int MoveFile(string sourceFileName, string destinationPath, bool showDialog, bool showProgress, bool autoRename, ref string errorMsg) { try { string sfName = GetFullName(sourceFileName); string dfName = GetFullName(destinationPath); return ToMoveOrCopy(wFunc.FO_MOVE, sfName, dfName, showDialog, showProgress, autoRename, ref errorMsg); } catch (Exception ex) { errorMsg = ex.Message; return -200; } } /// <summary> /// 移動一組檔案到指定的路徑下 /// </summary> /// <param name="sourceFileNames">要移動的檔案名稱數組</param> /// <param name="destinationPath">移動到的目的路徑</param> /// <param name="showDialog">指示是否顯示確認對話方塊,true-顯示確認對話方塊,false-不顯示確認對話方塊</param> /// <param name="showProgress">指示是否顯示進度對話方塊</param> /// <param name="autoRename">指示當檔案名稱重複時,是否自動為新檔案加上尾碼名</param> /// <param name="errorMsg">反饋錯誤訊息的字串</param> /// <returns>返回移動操作是否成功的標識,成功返回0,失敗返回錯誤碼,-200:表示其他異常</returns> public static int MoveFiles(string[] sourceFileNames, string destinationPath, bool showDialog, bool showProgress, bool autoRename, ref string errorMsg) { try { string sfName = ""; foreach (string str in sourceFileNames) { sfName += GetFullName(str) + "\0"; //組件檔案組字串 } string dfName = GetFullName(destinationPath); return ToMoveOrCopy(wFunc.FO_MOVE, sfName, dfName, showDialog, showProgress, autoRename, ref errorMsg); } catch (Exception ex) { errorMsg = ex.Message; return -200; } } #endregion 【移動檔案操作】 #region 【複製檔案操作】 /// <summary> /// 複製一個檔案到指定的檔案名稱或路徑 /// </summary> /// <param name="sourceFileName">要複製的檔案名稱</param> /// <param name="destinationFileName">複製到的目的檔案名稱或路徑</param> /// <param name="showDialog">指示是否顯示確認對話方塊,true-顯示確認對話方塊,false-不顯示確認對話方塊</param> /// <param name="showProgress">指示是否顯示進度對話方塊</param> /// <param name="autoRename">指示當檔案名稱重複時,是否自動為新檔案加上尾碼名</param> /// <returns>返回移動操作是否成功的標識,成功返回0,失敗返回錯誤碼,-200:表示其他異常</returns> public static int CopyFile(string sourceFileName, string destinationFileName, bool showDialog, bool showProgress, bool autoRename, ref string errorMsg) { try { string sfName = GetFullName(sourceFileName); string dfName = GetFullName(destinationFileName); return ToMoveOrCopy(wFunc.FO_COPY, sfName, dfName, showDialog, showProgress, autoRename, ref errorMsg); } catch (Exception ex) { errorMsg = ex.Message; return -200; } } /// <summary> /// 複製一組檔案到指定的路徑 /// </summary> /// <param name="sourceFileNames">要複製的檔案名稱數組</param> /// <param name="destinationPath">複製到的目的路徑</param> /// <param name="showDialog">指示是否顯示確認對話方塊,true-顯示確認對話方塊,false-不顯示確認對話方塊</param> /// <param name="showProgress">指示是否顯示進度對話方塊</param> /// <param name="autoRename">指示當檔案名稱重複時,是否自動為新檔案加上尾碼名</param> /// <returns>返回移動操作是否成功的標識,成功返回0,失敗返回錯誤碼,-200:表示其他異常</returns> public static int CopyFiles(string[] sourceFileNames, string destinationPath, bool showDialog, bool showProgress, bool autoRename, ref string errorMsg) { try { string sfName = ""; foreach (string str in sourceFileNames) { sfName += GetFullName(str) + "\0"; //組件檔案組字串 } string dfName = GetFullName(destinationPath); return ToMoveOrCopy(wFunc.FO_COPY, sfName, dfName, showDialog, showProgress, autoRename, ref errorMsg); } catch (Exception ex) { errorMsg = ex.Message; return -200; } } #endregion 【複製檔案操作】 #region 【重新命名檔案】 /// <summary> /// 重新命名一個檔案為新名稱,建議您使用更方便的Microsoft.VisualBasic.FileSystem.ReName();替換該方法 /// </summary> /// <param name="sourceFileName">要複製的檔案名稱</param> /// <param name="destinationFileName">複製到的目的檔案名稱或路徑</param> /// <param name="showDialog">指示是否顯示確認對話方塊,true-顯示確認對話方塊,false-不顯示確認對話方塊</param> /// <returns>返回移動操作是否成功的標識,成功返回0,失敗返回錯誤碼,-200:表示其他異常</returns> [Obsolete("建議使用 Microsoft.VisualBasic.FileSystem.ReName()方法")] public static int ReNameFile(string sourceFileName, string destinationFileName, bool showDialog, ref string errorMsg) { try { SHFILEOPSTRUCT lpFileOp = new SHFILEOPSTRUCT(); lpFileOp.wFunc = wFunc.FO_RENAME; lpFileOp.pFrom = GetFullName(sourceFileName) + "\0\0"; //將檔案名稱以結尾字元"\0\0"結束 lpFileOp.pTo = GetFullName(destinationFileName) + "\0\0"; lpFileOp.fFlags = FILEOP_FLAGS.FOF_NOERRORUI; if (!showDialog) lpFileOp.fFlags |= FILEOP_FLAGS.FOF_NOCONFIRMATION; //設定不顯示提示對話方塊 lpFileOp.fAnyOperationsAborted = true; int n = SHFileOperation(ref lpFileOp); if (n == 0) return 0; string tmp = GetErrorString(n); errorMsg = string.Format("{0}({1})", tmp, sourceFileName); return n; } catch (Exception ex) { errorMsg = ex.Message; return -200; } } /// <summary> /// 利用Microsoft.VisualBasic.FileSystem.ReName()方法實現 /// </summary> /// <param name="filePath"></param> /// <param name="newFileName"></param> public static void ReNameFile(string filePath, string newFileName) { try { string extensName = Path.GetExtension(filePath); string newName = newFileName + extensName; Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(filePath, newName); } catch (Exception ex) { throw ex; } } #endregion 【重新命名檔案】 /// <summary> /// 刪除單個或多個檔案 /// </summary> /// <param name="fileName">刪除的檔案名稱,如果是多個檔案,檔案名稱之間以字串結尾符'\0'隔開</param> /// <param name="toRecycle">指示是將檔案清除還是永久刪除,true-清除,false-永久刪除</param> /// <param name="showDialog">指示是否顯示確認對話方塊,true-顯示確認刪除對話方塊,false-不顯示確認刪除對話方塊</param> /// <param name="showProgress">指示是否顯示進度對話方塊,true-顯示,false-不顯示。該參數當指定永久刪除檔案時有效</param> /// <param name="errorMsg">反饋錯誤訊息的字串</param> /// <returns>操作執行結果標識,刪除檔案成功返回0,否則,返回錯誤碼</returns> private static int ToDelete(string fileName, bool toRecycle, bool showDialog, bool showProgress, ref string errorMsg) { SHFILEOPSTRUCT lpFileOp = new SHFILEOPSTRUCT(); lpFileOp.wFunc = wFunc.FO_DELETE; lpFileOp.pFrom = fileName + "\0"; //將檔案名稱以結尾字元"\0"結束 lpFileOp.fFlags = FILEOP_FLAGS.FOF_NOERRORUI; if (toRecycle) lpFileOp.fFlags |= FILEOP_FLAGS.FOF_ALLOWUNDO; //設定刪除到資源回收筒 if (!showDialog) lpFileOp.fFlags |= FILEOP_FLAGS.FOF_NOCONFIRMATION; //設定不顯示提示對話方塊 if (!showProgress) lpFileOp.fFlags |= FILEOP_FLAGS.FOF_SILENT; //設定不顯示進度對話方塊 lpFileOp.fAnyOperationsAborted = true; int n = SHFileOperation(ref lpFileOp); if (n == 0) return 0; string tmp = GetErrorString(n); //.av 檔案正常刪除了但也提示 402 錯誤,不知道為什麼。屏蔽之。 if ((fileName.ToLower().EndsWith(".av") && n.ToString("X") == "402")) return 0; errorMsg = string.Format("{0}({1})", tmp, fileName); return n; } /// <summary> /// 移動或複製一個或多個檔案到指定路徑下 /// </summary> /// <param name="flag">操作類型,是移動操作還是複製操作</param> /// <param name="sourceFileName">要移動或複製的檔案名稱,如果是多個檔案,檔案名稱之間以字串結尾符'\0'隔開</param> /// <param name="destinationFileName">移動到的目的位置</param> /// <param name="showDialog">指示是否顯示確認對話方塊,true-顯示確認對話方塊,false-不顯示確認對話方塊</param> /// <param name="showProgress">指示是否顯示進度對話方塊</param> /// <param name="autoRename">指示當檔案名稱重複時,是否自動為新檔案加上尾碼名</param> /// <param name="errorMsg">反饋錯誤訊息的字串</param> /// <returns>返回移動操作是否成功的標識,成功返回0,失敗返回錯誤碼</returns> private static int ToMoveOrCopy(wFunc flag, string sourceFileName, string destinationFileName, bool showDialog, bool showProgress, bool autoRename, ref string errorMsg) { SHFILEOPSTRUCT lpFileOp = new SHFILEOPSTRUCT(); lpFileOp.wFunc = flag; lpFileOp.pFrom = sourceFileName + "\0"; //將檔案名稱以結尾字元"\0\0"結束 lpFileOp.pTo = destinationFileName + "\0\0"; lpFileOp.fFlags = FILEOP_FLAGS.FOF_NOERRORUI; lpFileOp.fFlags |= FILEOP_FLAGS.FOF_NOCONFIRMMKDIR; //指定在需要時可以直接建立路徑 if (!showDialog) lpFileOp.fFlags |= FILEOP_FLAGS.FOF_NOCONFIRMATION; //設定不顯示提示對話方塊 if (!showProgress) lpFileOp.fFlags |= FILEOP_FLAGS.FOF_SILENT; //設定不顯示進度對話方塊 if (autoRename) lpFileOp.fFlags |= FILEOP_FLAGS.FOF_RENAMEONCOLLISION; //自動為重名檔案添加名稱尾碼 lpFileOp.fAnyOperationsAborted = true; int n = SHFileOperation(ref lpFileOp); if (n == 0) return 0; string tmp = GetErrorString(n); errorMsg = string.Format("{0}({1})", tmp, sourceFileName); return n; } /// <summary> /// 擷取一個檔案的全名 /// </summary> /// <param name="fileName">檔案名稱</param> /// <returns>返回組建檔案的完整路徑名</returns> private static string GetFullName(string fileName) { FileInfo fi = new FileInfo(fileName); return fi.FullName; } /// <summary> /// 解釋錯誤碼 /// </summary> /// <param name="n">代碼號</param> /// <returns>返回關於錯誤碼的文字描述</returns> private static string GetErrorString(int n) { if (n == 0) return string.Empty; switch (n) { case 2: return "系統找不到指定的檔案。"; case 7: return "儲存控制塊被銷毀。您是否選擇的“取消”操作?"; case 113: return "檔案已存在!"; case 115: return "重新命名檔案操作,原始檔案和目標檔案必須具有相同的路徑名。不能使用相對路徑。"; case 117: return "I/O控制錯誤"; case 123: return "指定了重複的檔案名稱"; case 116: return "The source is a root directory, which cannot be moved or renamed."; case 118: return "Security settings denied access to the source."; case 124: return "The path in the source or destination or both was invalid."; case 65536: return "An unspecified error occurred on the destination."; case 1026: return "在試圖移動或拷貝一個不存在的檔案."; case 1223: return "操作被取消!"; default: return "未識別的錯誤碼:" + n; } } }}