C# 文件操作封裝類(刪除,移動,復制,重命名)


最近發現群共享里面有個C# 文件操作封裝類,其方法是調用Windows API 來操作的文件的刪除、移動、復制、重命名操作。下載下來一試,發現果然不錯,特在此記錄,以防丟失!

文件操作類代碼如下:

C# 文件操作類
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;
            }
        }
    }
}

試驗源代碼在此下載:源代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM