【问题标题】:Recursively looping through a drive and replacing illegal characters递归循环遍历驱动器并替换非法字符
【发布时间】:2012-05-23 23:17:46
【问题描述】:

我必须创建一个应用程序来钻取特定驱动器,读取所有文件名并用下划线替换非法 SharePoint 字符。 我指的非法字符是:~ # % & * {} / \ | : <> ? - ""

有人可以提供代码链接或代码本身如何执行此操作吗?我对 C# 非常陌生,需要我能得到的所有帮助。我研究了有关递归钻取驱动器的代码,但我不确定如何将字符替换和递归循环放在一起。请帮忙!

【问题讨论】:

  • [1] 当您说“替换”时,您的意思是重命名文件吗? [2] 如果您的代码可以简单地列出所有文件,那么您就快到了:编辑您的问题并添加代码。然后很容易告诉你该怎么做。
  • 我在这里创建了一个新问题:stackoverflow.com/questions/3015965/…

标签: c# recursion replace


【解决方案1】:

删除非法字符的建议在这里:

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);

【讨论】:

  • 使用 SPUrlUtility.IsLegalCharInUrl(char character) 确定非法的“SharePoint”文件字符。
  • @Jared:这些 Enumerate* 方法是新的,我认为在 .NET 4 中。正如您可以想象的那样,它们返回 IEnumerable 而不是某种列表。
【解决方案2】:

不是真正的答案,但请考虑以下两个方面:

以下字符在文件名中无论如何都无效,因此您不必担心它们:/\:*?"&lt;&gt;|

确保您的算法正确处理重复名称。例如,My~Project.docMy#Project.doc 都将重命名为 My_Project.doc

【讨论】:

    【解决方案3】:

    重命名文件夹中的文件的递归方法是您想要的。只需将根文件夹传递给它,它就会为找到的所有子文件夹调用自己。

    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. 这不会检查两个文件是否具有相似的名称,例如 thing~ 和 thing%

    【讨论】:

    • 向 Steven (+1) 表示感谢,感谢我在我的笔记 #2 中指出重复文件问题
    • 或者创建一个数组:char[] invalidList = new char[] { '~', '#', ... } 并使用循环替换:foreach (char invalid in invalidList) { newName = newName.Replace(invalid, '_'); } 但是,由于它是不可变的,因此每次都必须创建一个新字符串。也许正则表达式会因为这个原因而更快?
    【解决方案4】:
    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);
        }
    }
    

    虽然这不会像 Steven 指出的那样处理重复的名称。

    【讨论】:

      猜你喜欢
      • 2015-01-17
      • 2014-02-24
      • 1970-01-01
      • 2013-04-18
      • 2019-10-31
      • 2014-12-15
      • 1970-01-01
      • 1970-01-01
      • 2011-04-18
      相关资源
      最近更新 更多