Рекурсивная установка атрибутов файлов в подпапках

У меня возникли проблемы с попыткой установить атрибуты для папок, внутри которых были файлы, для которых было установлено значение «Только чтение». Я мог установить атрибуты папки, но не файлы внутри.

Это установит атрибуты, включая подпапки, а затем удалит. Нашла информацию о codeproject.

использовать это:

ScanDirectory scanDirectory = new ScanDirectory();  
scanDirectory.WalkDirectory(@"/Storage Card");

public class ScanDirectory
{
    public void WalkDirectory(string directory)
    {
        WalkDirectory(new DirectoryInfo(directory));
    }

    private void WalkDirectory(DirectoryInfo directory)
    {
        // Scan all files in the current path
        foreach (FileInfo file in directory.GetFiles())
        {
            file.Attributes &= ~FileAttributes.ReadOnly;
            file.Delete();
        }

        DirectoryInfo[] subDirectories = directory.GetDirectories();

        // Scan the directories in the current directory and call this method 
        // again to go one level into the directory tree
        foreach (DirectoryInfo subDirectory in subDirectories)
        {
            WalkDirectory(subDirectory);
            subDirectory.Attributes &= ~FileAttributes.ReadOnly;

            subDirectory.Delete();
        }
    }
}

person user2190928    schedule 24.06.2013    source источник
comment
Я думаю, что все ваши потребности покрываются этим вопросом: stackoverflow.com/questions/611921/ :-)   -  person C4stor    schedule 24.06.2013


Ответы (2)


Вы можете создать рекурсивную функцию для выполнения этой работы:

    private void UpdateFileAttributes(DirectoryInfo dInfo)
    {
        // Set Directory attribute
        dInfo.Attributes &= ~FileAttributes.ReadOnly;

        // get list of all files in the directory and clear 
        // the Read-Only flag

        foreach (FileInfo file in dInfo.GetFiles())
        {
            file.Attributes &= ~FileAttributes.ReadOnly;
        }

        // recurse all of the subdirectories
        foreach (DirectoryInfo subDir in dInfo.GetDirectories())
        {
            UpdateFileAttributes(subDir);
        }
    }
person someuser    schedule 14.10.2013

Вы можете использовать поиск по глубине (версия стека) или поиск по дыханию (версия с очередью) для обхода дерева, чтобы увидеть ваши папки, примерно так:

static void Main(String[] args)
{
    // Using breath-first search (BFS)
    Queue<DirectoryInfo> myQueue = new Queue<DirectoryInfo>();

    // Your storage path here
    myQueue.Enqueue(new DirectoryInfo("C:\\"));

    while(myQueue.Count > 0)
    {
        // Look at the current directory
        DirectoryInfo crtDI = myQueue.Dequeue();

        // Put the directories from the crt dir in a queue
        foreach (DirectoryInfo otherDir in GetCrtDirectories(crtDI))
            myQueue.Enqueue(otherDir);

        // Do what you want with the directory here 
        FixAccess(crtDI);
    }
}

private static IEnumerable<DirectoryInfo> GetCrtDirectories(DirectoryInfo crtDI)
{
    foreach(string dirStr in Directory.GetDirectories(crtDI.FullName))
    {
        DirectoryInfo newDir = new DirectoryInfo(dirStr);
        yield return newDir;
    }
}

private static void FixAccess (DirectoryInfo DI)
{
    foreach (string fileName in System.IO.Directory.GetFiles(DI.FullName))
    {
        FileInfo fileInfo = new FileInfo(fileName);
        FileAttributes attributes = fileInfo.Attributes;

        if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
        {
            // set the attributes to nonreadonly
            fileInfo.Attributes &= ~FileAttributes.ReadOnly;
        }
    }
}
person Thanatos    schedule 24.06.2013
comment
Я не получал никаких ошибок с этим методом, но по какой-то причине не менял разрешения. Я установил папку в корне карты памяти только для чтения и файл внутри. Все еще работаю над этим. - person user2190928; 24.06.2013
comment
Попробуйте вставить Console.WriteLine (crtDI.FullName) перед FixAccess (crtDI) или MessageBox.Show (crtDI.FullName), чтобы проверить, перечислены ли в методе все папки в каталоге хранилища. Если да, значит, метод FixAccess не работает. - person Thanatos; 24.06.2013
comment
Я отредактировал сообщение методом, который пытаюсь. Я не понимаю, как это назвать. Мне кажется намного проще для новичка, если он работает. - person user2190928; 24.06.2013
comment
@ user2190928 Создайте консольное приложение, вставьте мой код, измените частный статический void FixAccess (DirectoryInfo DI) {Console.WriteLine (DI.FullName); }, но я предполагаю, что вы запутались в статических методах, если вы используете экземпляры класса, вы должны удалить статику из всех методов. - person Thanatos; 24.06.2013
comment
вы должны вызвать метод с помощью Main (null) или полностью удалить аргументы String [] из Main и просто называть его Main () или называть его как хотите. - person Thanatos; 24.06.2013