Рекурсивный цикл по диску и замена недопустимых символов - PullRequest
3 голосов
/ 18 мая 2010

Мне нужно создать приложение, которое сверлит данные на конкретном диске, считывает все имена файлов и заменяет недопустимые символы SharePoint подчеркиванием. Недопустимые символы, на которые я ссылаюсь: ~ # % & * {} / \ | : <> ? - ""

Может ли кто-нибудь предоставить ссылку на код или сам код о том, как это сделать? Я ОЧЕНЬ новичок в C # и мне нужна вся помощь, которую я могу получить. Я исследовал код рекурсивного сверления диска, но я не уверен, как соединить символ и рекурсивный цикл. Пожалуйста, помогите!

Ответы [ 4 ]

6 голосов
/ 18 мая 2010

Не совсем ответ, но учтите оба следующих момента:

Следующие символы недопустимы в именах файлов, поэтому вам не нужно беспокоиться о них: /\:*?"<>|.

Убедитесь, что ваш алгоритм правильно обрабатывает дубликаты имен.Например, My~Project.doc и My#Project.doc будут оба переименованы в My_Project.doc.

6 голосов
/ 18 мая 2010

Советы по удалению недопустимых символов здесь:

Как удалить недопустимые символы из пути и имени файла?

Вам просто нужно изменить набор символов на набор символов, который вы хотите удалить.

Если вы выяснили, как просматривать папки, вы можете получить все файлы в каждой папке с помощью:

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);
2 голосов
/ 18 мая 2010

Рекурсивный метод переименования файлов в папках - это то, что вам нужно. Просто передайте ему корневую папку, и она вызовет себя для всех найденных подпапок.

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. Это не проверяет, имеют ли два файла одинаковые имена, такие как вещь ~ и вещь%
1 голос
/ 18 мая 2010
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);
    }
}

Хотя это не будет обрабатывать дубликаты имен, как указал Стивен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...