Недавно я переместил кучу MP3 из разных мест в хранилище. Я создавал новые имена файлов, используя теги ID3 (спасибо, TagLib-Sharp!), И я заметил, что получаю System.NotSupportedException
:
Msgstr "Формат данного пути не поддерживается."
Это было сгенерировано либо File.Copy()
или Directory.CreateDirectory()
.
Это не заняло много времени, чтобы понять, что мои имена файлов должны быть очищены. Итак, я сделал очевидную вещь:
public static string SanitizePath_(string path, char replaceChar)
{
string dir = Path.GetDirectoryName(path);
foreach (char c in Path.GetInvalidPathChars())
dir = dir.Replace(c, replaceChar);
string name = Path.GetFileName(path);
foreach (char c in Path.GetInvalidFileNameChars())
name = name.Replace(c, replaceChar);
return dir + name;
}
К моему удивлению, я продолжал получать исключения. Оказалось, что ':' не входит в набор Path.GetInvalidPathChars()
, потому что он действителен в корне пути. Я полагаю, это имеет смысл, но это должно быть довольно распространенной проблемой. У кого-нибудь есть какой-нибудь короткий код, который очищает путь? Самое тщательное, что я придумал, но такое ощущение, что это, вероятно, излишне.
// replaces invalid characters with replaceChar
public static string SanitizePath(string path, char replaceChar)
{
// construct a list of characters that can't show up in filenames.
// need to do this because ":" is not in InvalidPathChars
if (_BadChars == null)
{
_BadChars = new List<char>(Path.GetInvalidFileNameChars());
_BadChars.AddRange(Path.GetInvalidPathChars());
_BadChars = Utility.GetUnique<char>(_BadChars);
}
// remove root
string root = Path.GetPathRoot(path);
path = path.Remove(0, root.Length);
// split on the directory separator character. Need to do this
// because the separator is not valid in a filename.
List<string> parts = new List<string>(path.Split(new char[]{Path.DirectorySeparatorChar}));
// check each part to make sure it is valid.
for (int i = 0; i < parts.Count; i++)
{
string part = parts[i];
foreach (char c in _BadChars)
{
part = part.Replace(c, replaceChar);
}
parts[i] = part;
}
return root + Utility.Join(parts, Path.DirectorySeparatorChar.ToString());
}
Любые улучшения, чтобы сделать эту функцию более быстрой и менее барочной, будут высоко оценены.
источник
Ответы:
Чтобы очистить имя файла, вы можете сделать это
источник
GetInvalidFileNameChars
не включают их. Он не генерирует исключение в окнах, он просто удаляет их, но может вызвать неожиданное поведение, если вы ожидаете, что период будет там. Я изменил регулярное выражение для обработки этого случая, чтобы.
он считался одним из недопустимых символов, если он находится в конце строки.Более короткое решение:
источник
Основываясь на превосходном ответе Андре, но принимая во внимание комментарий Спуда к зарезервированным словам, я сделал эту версию:
И это мои юнит-тесты
источник
COM1
), которые также запрещены. Предложенное исправление будет состоять в том, чтобы изменить зарезервированныйWordPattern"^{0}(\\.|$)"
и заменяющую строку на"_reservedWord_$1"
источник
String.Concat(dirty...)
вместоJoin(String.Empty...
Я использую
System.IO.Path.GetInvalidFileNameChars()
метод для проверки недопустимых символов, и у меня нет проблем.Я использую следующий код:
источник
Я хотел каким-то образом сохранить символы, а не просто заменить символ подчеркиванием.
Один из способов, который я подумал, - это заменить символы похожими на символы, которые (в моей ситуации) вряд ли будут использоваться в качестве обычных символов. Таким образом, я взял список недопустимых символов и нашел, что они похожи.
Ниже приведены функции для кодирования и декодирования с использованием аналогичных элементов.
Этот код не включает полный список всех символов System.IO.Path.GetInvalidFileNameChars (). Так что это зависит от вас, чтобы расширить или использовать замену подчеркивания для любых оставшихся символов.
Вы можете выбрать свои собственные приглядывания. Я использовал приложение «Карта персонажей» в Windows, чтобы выбрать мое
%windir%\system32\charmap.exe
Поскольку я делаю настройки через открытие, я обновлю этот код.
источник
!"#$%&'()*+,-./:;<=>?@{|}~
или другие формы, такие как/
SOLIDUS и `FR` FRACTION SLASH, которые можно без проблем использовать непосредственно в именах файловЯ думаю, проблема в том, что вы сначала вызываете
Path.GetDirectoryName
плохую строку. Если в нем есть символы не из имен файлов, .Net не может определить, какие части строки являются каталогами и выбрасывает. Вы должны сделать сравнение строк.Предполагая, что это только имя файла, а не весь путь, попробуйте это:
источник
Я имел успех с этим в прошлом.
Хороший, короткий и статичный :-)
источник
Здесь много рабочих решений. только для полноты, вот подход, который не использует регулярные выражения, но использует LINQ:
Кроме того, это очень короткое решение;)
источник
Вот эффективный метод расширения отложенной загрузки, основанный на коде Андре:
источник
Ваш код будет чище, если вы добавите каталог и имя файла вместе и очистите их, а не очистите их независимо. Что касается очистки от:, просто возьмите 2-й символ в строке. Если он равен «replacechar», замените его двоеточием. Поскольку это приложение для вашего собственного использования, такого решения должно быть вполне достаточно.
источник
источник