вторник, 31 января 2012 г.

Полезные расширения для работы с папками

Несмотря на стремительное развитие облачных технологий, простому программисту .NET никуда не деться от работы с файловой системой. Благодаря классам из пространства имен System.IO, работа с файлами и папками довольно проста и прозрачна. Но, все таки, некоторые простые (и довольно востребованные) операции требуют заметного количества манипуляций. Предлагаю вашему вниманию несколько методов-расширений для класса DirectoryInfo, которые слегка дополнят возможности по работе с папками.

Встречайте! Буду признателен за любые дополнения и комментарии.

Содержит ли папка файл

Этот метод проверяет, содержит ли папка указанный файл или директорию:

/// <summary>
/// Проверяет, принадлежит ли папка (или файл) с указанным путем текущей папке
/// </summary>
public static bool IsParentOf(this DirectoryInfo source, String childDirPath)
{
    Contract.IsNotNull(source);
 
    DirectoryInfo parent = Directory.GetParent(childDirPath);
    if (parent == null)
        return false;
 
    if (string.Compare(parent.FullName, source.FullName, true) == 0)
        return true;
 
    if (IsParentOf(source, parent.FullName))
        return true;
    
    return false;
}

Пуста ли папка


Этот метод проверяет, содержит ли папка другие папки или файлы:



public static bool IsEmpty(this DirectoryInfo source)
{
    Contract.IsNotNull(source);
 
    return (source.GetFiles().Length == 0) && 
           (source.GetDirectories().Length == 0);
}

Скопировать папку со всем содержимым


Как ни удивительно, стандартная библиотека не включает метода копирования папки со всеми файлами. Метод ниже восполняет этот пробел.



/// <summary>
/// Копирует папку со всем ее содержимым по указанному пути
/// </summary>
/// <param name="targetPath">Путь конечной папки</param>
public static void CopyTo(this DirectoryInfo source, String targetPath)
{
    Contract.IsNotNull(source);
    /// Если папка targetPath находится в исходной папке source
    Contract.IsFalse(source.IsParentOf(targetPath));
 
    if (!Directory.Exists(targetPath))
        Directory.CreateDirectory(targetPath);
 
    /// Копируем файлы
    foreach (FileInfo fi in source.GetFiles())
        fi.CopyTo(Path.Combine(targetPath, fi.Name), true);
 
    /// Рекурсивно копируем поддиректории
    foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
        diSourceSubDir.Copy(Path.Combine(targetPath, diSourceSubDir.Name));
}

Открыть в проводнике


Открыть папку в проводнике просто, нужно лишь вызвать Process.Start, передав ему путь к папке. Но удобнее оформить это в виде отдельного метода – это дает возможность отслеживать в коде именно открытие папки, а не просто запуски внешних приложений.


Открыть папку в проводнике:



/// <summary>
/// Открыть папку в проводнике
/// </summary>
public static void Open(this DirectoryInfo source)
{
    Contract.IsNotNull(source);
    System.Diagnostics.Process.Start(source.FullName);
}

Открыть в проводнике родительскую папку, установив выбор на указанный файл или папку:



public static void Select(this FileSystemInfo source)
{
    Contract.IsNotNull(source);
    System.Diagnostics.Process.Start("explorer.exe", @"/select, " + source.FullName);
}

Выборочно удалить файлы в папки


Иногда бывает нужно удалить все файлы в папке, а иногда требуется удалить только некоторые (старые, сильно большие, временные и т.п.). Данный метод запускает удаление с предикатом.



/// <summary>
/// очищает содержимое папки, соответствующее указанному предикату
/// </summary>
/// <param name="source"></param>
public static void DeleteContent(this DirectoryInfo source, 
                                 Func<string, bool> DeletePredicate)
{
    source.GetFiles().Where(f => DeletePredicate(f.FullName)).ForEach(f => f.Delete());
    source.GetDirectories().Where(f => DeletePredicate(f.FullName)).ForEach(d =>
        {
            d.DeleteContent(DeletePredicate);
            if (d.CheckIsEmpty())
                d.Delete(false);
        });
}

Комментариев нет:

Отправить комментарий