Библиотека управления путями .NET

Кто-нибудь знает какую-нибудь хорошую библиотеку, которая хорошо абстрагирует проблему манипулирования путями? Я хотел бы иметь возможность комбинировать и анализировать пути с произвольными разделителями (например, '/' или ':'), не изобретая велосипед.

Жаль, что System.IO.Path нельзя использовать повторно.

Спасибо


person Kent Boogaart    schedule 09.09.2008    source источник
comment
Я думаю, что System.IO.Path отлично работает. У вас есть конкретные задачи, которые вам нужны, с которыми он не может справиться?   -  person Espo    schedule 09.09.2008
comment
Можно ли использовать Path.DirectorySeparatorChar?   -  person Ian Oxley    schedule 09.09.2008
comment
@Espo: попробуйте прочитать второе предложение моего вопроса.   -  person Kent Boogaart    schedule 23.08.2009


Ответы (5)


System.IO.Path.Combine отлично подходит для многих типов путей:

http://msdn.microsoft.com/en-us/library/system.io.path.combine.aspx

System.IO.Path.Combine использует стандартные разделители текущей платформы для объединения путей. Это означает, что в Windows он использует «\», а в unix/linux (моно) — «/». Можете ли вы привести примеры того, какие пути вы пытаетесь комбинировать и на какой платформе?

person Espo    schedule 09.09.2008
comment
Боюсь, System.IO.Path не помогает, потому что символы-разделители, которые он использует и понимает, предопределены. Как я уже сказал, мне нужно использовать произвольные символы-разделители, такие как ':' и '/'. Лучшее, что я могу сделать с System.IO.Path, это преобразовать мои произвольные символы в те, которые он распознает (например, '\'), а затем снова преобразовать обратно. Но это в лучшем случае хакерское решение. - person Kent Boogaart; 23.08.2009

Проверьте библиотеку Патрика, чтобы обрабатывать операции с путями текст ссылки

Это проект codeplex.

person Aaron Fischer    schedule 10.09.2008
comment
Спасибо - эта библиотека выглядит полезной, но она по-прежнему не позволяет указывать собственный разделитель пути. Он просто использует Path.DirectorySeparatorChar. - person Kent Boogaart; 11.09.2008

Вы описываете регулярные выражения! Используйте это как основу для того, что вам нужно сделать.

person rp.    schedule 09.09.2008
comment
Конечно, регулярные выражения будут работать, и это то, что я использовал до сих пор. Но они кажутся излишними и вряд ли будут работать так же хорошо, как выделенная библиотека управления путями. В конце концов, System.IO.Path не использует регулярные выражения в своей реализации, не так ли? - person Kent Boogaart; 23.08.2009

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

Так что, взяв за основу рефлектор и System.IO.Path, несложно изобрести велосипед.

  • Создайте экземпляр этого класса
  • Укажите символы-разделители в CTor.
  • При необходимости измените InvalidPathChars, если это необходимо.

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

class ArbitraryPath
{
    private readonly char _directorySeparatorChar;
    private readonly char _altDirectorySeparatorChar;
    private readonly char _volumeSeparatorChar;

    public ArbitraryPath(char directorySeparatorChar, char altDirectorySeparatorChar, char volumeSeparatorChar)
    {
        _directorySeparatorChar = directorySeparatorChar;
        _altDirectorySeparatorChar = altDirectorySeparatorChar;
        _volumeSeparatorChar = volumeSeparatorChar;
    }

    public string Combine(string path1, string path2)
    {
        if ((path1 == null) || (path2 == null))
        {
            throw new ArgumentNullException((path1 == null) ? "path1" : "path2");
        }
        CheckInvalidPathChars(path1);
        CheckInvalidPathChars(path2);
        if (path2.Length == 0)
        {
            return path1;
        }
        if (path1.Length == 0)
        {
            return path2;
        }
        if (IsPathRooted(path2))
        {
            return path2;
        }

        char ch = path1[path1.Length - 1];
        if (ch != _directorySeparatorChar && ch != _altDirectorySeparatorChar && ch != _volumeSeparatorChar)
        {
            return (path1 + _directorySeparatorChar + path2);
        }
        return (path1 + path2);
    }

    public bool IsPathRooted(string path)
    {
        if (path != null)
        {
            CheckInvalidPathChars(path);
            int length = path.Length;
            if (length >= 1 && (path[0] == _directorySeparatorChar || path[0] == _altDirectorySeparatorChar) || length >= 2 && path[1] == _volumeSeparatorChar)
            {
                return true;
            }
        }
        return false;
    }

    internal static void CheckInvalidPathChars(string path)
    {
        for (int i = 0; i < path.Length; i++)
        {
            int num2 = path[i];
            if (num2 == 0x22 || num2 == 60 || num2 == 0x3e || num2 == 0x7c || num2 < 0x20)
            {
                throw new ArgumentException("Argument_InvalidPathChars");
            }
        }
    } 

}
person Bob    schedule 28.10.2009

Боюсь, вам придется реализовать путь оцените себя, как это сделал я. Это дает следующие преимущества:

  • вы можете извлечь выгоду из безопасности типов
  • вы можете переопределить оператор /, что упрощает конкатенацию
  • вы можете добавить удобные функции-члены, такие как GetParentPath() и GetLeafPart()
person Dimitri C.    schedule 09.09.2010