2010-05-18 37 views
3

我必須創建一個應用程序,該應用程序可以鑽入特定驅動器,讀取所有文件名並用下劃線替換非法SharePoint字符。 我指的非法字符是:~ # % & * {}/\ | : <> ? - ""遞歸循環訪問驅動器並替換非法字符

有人可以提供代碼的鏈接或代碼本身如何做到這一點?我對C#非常陌生,需要我可能獲得的所有幫助。我已經研究了通過驅動器遞歸鑽取的代碼,但我不知道如何將字符替換和遞歸循環放在一起。請幫忙!

+1

[1]當你說「替換」你的意思是,重命名文件? [2]如果你有簡單列出所有文件的代碼,你幾乎就在那裏:編輯你的問題並添加代碼。那麼很容易就能告訴你該怎麼做。 – egrunin 2010-05-18 15:46:01

+0

我在這裏創建了一個新問題: http://stackoverflow.com/questions/3015965/changing-filenames-using-regex-and-recursion – yeahumok 2010-06-10 15:41:20

回答

6

去除非法字符的建議是在這裏:

How to remove illegal characters from path and filenames?

你只需要改變的字符集的組要刪除的字符。

如果你已經找到了如何遞歸的文件夾,你可以得到所有的文件,每個文件夾中:

var files = System.IO.Directory.EnumerateFiles(currentPath); 

然後

foreach (string file in files) 
{ 
    System.IO.File.Move(file, ConvertFileName(file)); 
} 

的ConvertFileName方法,你會寫信給接受一個文件名作爲一個字符串,並返回一個文件名被剝奪的壞字符。

請注意,如果您使用的是.NET 3.5,GetFiles()也可以。根據MSDN:

的EnumerateFiles和GetFiles的 方法的區別如下:當您使用 EnumerateFiles,你就可以開始 列舉名稱 收集整個集合之前 返回;當您使用GetFiles時, 必須等待返回整個數組名稱 才能訪問 數組。因此,當您使用 許多文件和 目錄時,EnumerateFiles可以更高效地爲 。


如何遞歸地列出目錄

string path = @"c:\dev"; 
string searchPattern = "*.*"; 

string[] dirNameArray = Directory.GetDirectories(path, searchPattern, SearchOption.AllDirectories); 

// Or, for better performance: 
// (but breaks if you don't have access to a sub directory; see 2nd link below) 
IEnumerable<string> dirNameEnumeration = Directory.EnumerateDirectories(path, searchPattern, SearchOption.AllDirectories); 
+3

+1:不知道Directory.EnumerateFiles(x) – 2010-05-18 15:57:33

+3

使用SPUrlUtility.IsLegalCharInUrl(char字符)來確定非法的「SharePoint」文件char。 – Stefan 2010-05-18 16:06:20

+1

@Jared:那些枚舉*方法是新的,我想在.NET 4中。正如你可以想象的那樣,它們返回IEnumerable而不是某種列表。 – 2010-05-18 16:09:34

6

不是一個真正的答案,但考慮博以下各項中的第幾個:

以下字符在文件名中無效,因此您不必擔心它們:/\:*?"<>|

確保您的算法適當地處理了重複的名稱。例如,My~Project.docMy#Project.doc都將重命名爲My_Project.doc

2

重命名文件夾中的文件的遞歸方法是你想要的。只需將它傳遞給根文件夾,它就會爲所有找到的子文件夾調用它自己。

private void SharePointSanitize(string _folder) 
{ 
    // Process files in the directory 
    string [] files = Directory.GetFiles(_folder); 
    foreach(string fileName in files) 
    { 
     File.Move(fileName, SharePointRename(fileName)); 
    } 
    string[] folders = Directory.GetDirectories(_folder); 
    foreach(string folderName in folders) 
    { 
     SharePointSanitize(folderName); 
    } 
} 

private string SharePointRename(string _name) 
{ 
    string newName = _name; 
    newName = newName.Replace('~', ''); 
    newName = newName.Replace('#', ''); 
    newName = newName.Replace('%', ''); 
    newName = newName.Replace('&', ''); 
    newName = newName.Replace('*', ''); 
    newName = newName.Replace('{', ''); 
    newName = newName.Replace('}', ''); 
    // .. and so on 
    return newName; 
} 

注:

  1. 您可以在SharePointRename()方法你要替換,如下劃線任何字符替換''
  2. 這並不檢查兩個文件有這樣的東西〜和事情%
+0

支持Steven(+1)注意到我的註釋#2中的重複文件問題 – JYelton 2010-05-18 16:02:12

+0

或者創建一個數組:'char [] invalidList = new char [] {'〜','#',...}和使用循環來替換:'foreach(invalidList in invalidList){newName = newName.Replace(invalid,'_'); }'但是,每次都必須創建一個新的字符串,因爲它是不可變的。也許正因爲這個原因,正則表達式會更快? – 2010-05-18 16:14:18

1
class Program 
{ 
    private static Regex _pattern = new Regex("[~#%&*{}/\\|:<>?\"-]+"); 
    static void Main(string[] args) 
    { 
     DirectoryInfo di = new DirectoryInfo("C:\\"); 
     RecursivelyRenameFilesIn(di); 
    } 

    public static void RecursivelyRenameFilesIn(DirectoryInfo root) 
    { 
     foreach (FileInfo fi in root.GetFiles()) 
      if (_pattern.IsMatch(fi.Name)) 
       fi.MoveTo(string.Format("{0}\\{1}", fi.Directory.FullName, Regex.Replace(fi.Name, _pattern.ToString(), "_"))); 

     foreach (DirectoryInfo di in root.GetDirectories()) 
      RecursivelyRenameFilesIn(di); 
    } 
} 

相似的名稱雖然這不會處理重複的名稱作爲史蒂芬指出。