最近一直在弄文件傳輸組件,其中一個功能就是,在接收端接收文件時,如果文件已經存在了,則對其進行文件名+索引的方式進行自動重命名,之前也寫個類似的工具類,總感覺代碼太冗余,每回頭想想,總覺得心里有疙瘩,下班的時候在地鐵上,又想了想,感覺是我把問題想復雜了,遂將今天的思路整理一下,寫了一個輔助類,記錄在此。
[工具類]文件或文件夾xx已存在,則重命名為xx(n)
1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Linq; 5 using System.Text; 6 using System.Text.RegularExPRessions; 7 using System.Threading.Tasks; 8 9 namespace Wolfy.ReNameHelper10 {11 /// <summary>12 /// 文件已存在,重命名操作類13 /// </summary>14 public class ReNameHelper15 {16 /// <summary>17 /// 對文件進行重命名18 /// </summary>19 /// <param name="strFilePath"></param>20 /// <returns></returns>21 public static string FileReName(string strFilePath)22 {23 //判斷該文件是否存在,存在則返回新名字,否則返回原來的名24 if (!File.Exists(strFilePath))25 {26 return Path.GetFileName(strFilePath);27 }28 else29 {30 //獲取不帶擴展名的文件名稱31 string strFileNameWithoutExtension = Path.GetFileNameWithoutExtension(strFilePath);32 //獲取擴展名33 string strFileExtension = Path.GetExtension(strFilePath);34 //獲取目錄名35 string strDirPath = Path.GetDirectoryName(strFilePath);36 //以文件名開頭和結尾的正則37 string strRegex = "^" + strFileNameWithoutExtension + "(//d+)?" ;38 Regex regex = new Regex(strRegex);39 //獲取該路徑下類似的文件名40 string[] strFilePaths = Directory.GetFiles(strDirPath, "*" + strFileExtension).Where(path => regex.IsMatch(Path.GetFileNameWithoutExtension(path))).ToArray();41 //獲得新的文件名42 return strFileNameWithoutExtension + "(" + (strFilePaths.Length + 1).ToString() + ")" + strFileExtension;43 }44 }45 /// <summary>46 /// 文件夾已存在,重命名47 /// </summary>48 /// <param name="strFolderPath"></param>49 /// <returns></returns>50 public static string FolderReName(string strFolderPath)51 {52 //判斷該文件夾是否存在,存在則返回新名字,否則返回原來的名53 if (!Directory.Exists(strFolderPath))54 {55 return Path.GetFileName(strFolderPath);56 }57 else58 {59 //獲取文件夾名60 string strFolderName= Path.GetFileName(strFolderPath);61 //獲取目錄名62 string strDirPath = Path.GetDirectoryName(strFolderPath);63 //以文件夾名開頭和結尾的正則64 string strRegex = "^" + strFolderName + "(//d+)?";65 Regex regex = new Regex(strRegex);66 //獲取該路徑下類似的文件夾名67 string[] strFilePaths = Directory.GetDirectories(strDirPath).Where(path => regex.IsMatch(Path.GetFileName(path))).ToArray();68 //獲得新的文件名69 return strFolderName + "(" + (strFilePaths.Length + 1).ToString() + ")" ;70 }71 }72 }73 }
實現思路:使用正則進行匹配以文件名或者文件夾名字開頭的文件或者文件夾名稱,獲取文件或者文件夾的個數,則新的文件名為文件名(文件或者文件夾總數+1)。當然,對一些,名字比較特殊的,不符合windows命名規則的,在客戶端選擇文件或者文件夾的時候,盡量對其進行過濾。以保證該輔助類起到應有的作用。
簡單測試

在路徑C:/Users/Wolfy/Desktop/MVC5下有如上圖的一些文件,現在如果再次接收相同名字的文件或者文件夾,則返回新的文件或者文件夾名
結果

這里也分享一個園友寫的一個重命名的輔助類。對文件操作的輔助類,記錄再次,供大家參考。
原文地址:http://m.survivalescaperooms.com/lxblog/archive/2012/11/13/2768096.html

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[] fileNa
新聞熱點
疑難解答