Ich habe kürzlich eine Reihe von MP3s von verschiedenen Orten in ein Repository verschoben. Ich hatte die neuen Dateinamen mit den ID3-Tags erstellt (danke, TagLib-Sharp!) Und bemerkte, dass ich Folgendes bekam System.NotSupportedException
:
"Das Format des angegebenen Pfads wird nicht unterstützt."
Dies wurde entweder von File.Copy()
oder generiert Directory.CreateDirectory()
.
Es dauerte nicht lange, bis mir klar wurde, dass meine Dateinamen bereinigt werden mussten. Also habe ich das Offensichtliche getan:
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;
}
Zu meiner Überraschung bekam ich weiterhin Ausnahmen. Es stellte sich heraus, dass ':' nicht in der Menge von enthalten ist Path.GetInvalidPathChars()
, da es in einer Pfadwurzel gültig ist. Ich nehme an, das macht Sinn - aber das muss ein ziemlich häufiges Problem sein. Hat jemand einen Funktionscode, der einen Pfad bereinigt? Das gründlichste, was ich mir ausgedacht habe, aber es fühlt sich wahrscheinlich übertrieben an.
// 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());
}
Alle Verbesserungen, um diese Funktion schneller und weniger barock zu machen, wären sehr dankbar.
quelle
Antworten:
Um einen Dateinamen zu bereinigen, können Sie dies tun
quelle
GetInvalidFileNameChars
nicht enthalten sind. Es löst keine Ausnahme in Windows aus, es entfernt sie nur, aber es kann zu unerwartetem Verhalten führen, wenn Sie erwarten, dass der Zeitraum dort ist. Ich habe den regulären Ausdruck so geändert, dass dieser Fall behandelt wird,.
damit er als eines der ungültigen Zeichen betrachtet wird, wenn er sich am Ende der Zeichenfolge befindet.Eine kürzere Lösung:
quelle
Basierend auf Andres ausgezeichneter Antwort, aber unter Berücksichtigung von Spuds Kommentar zu reservierten Wörtern, habe ich diese Version gemacht:
Und das sind meine Unit-Tests
quelle
COM1
), die ebenfalls nicht zulässig sind. Vorgeschlagene Lösung wäre, das reservierte"^{0}(\\.|$)"
"_reservedWord_$1"
quelle
String.Concat(dirty...)
stattJoin(String.Empty...
Ich verwende die
System.IO.Path.GetInvalidFileNameChars()
Methode, um ungültige Zeichen zu überprüfen, und habe keine Probleme.Ich verwende den folgenden Code:
quelle
Ich wollte die Zeichen auf irgendeine Weise beibehalten und nicht nur durch einen Unterstrich ersetzen.
Eine Möglichkeit, die ich dachte, bestand darin, die Zeichen durch ähnlich aussehende Zeichen zu ersetzen, die (in meiner Situation) wahrscheinlich nicht als reguläre Zeichen verwendet werden. Also nahm ich die Liste der ungültigen Zeichen und fand Look-a-Likes.
Das Folgende sind Funktionen zum Codieren und Decodieren mit den Look-a-Likes.
Dieser Code enthält keine vollständige Liste aller System.IO.Path.GetInvalidFileNameChars () -Zeichen. Es liegt also an Ihnen, den Unterstrichersatz für alle verbleibenden Zeichen zu erweitern oder zu verwenden.
Sie können Ihre eigenen Look-a-Likes auswählen. Ich habe die Character Map App in Windows verwendet, um meine auszuwählen
%windir%\system32\charmap.exe
Wenn ich durch Erkennung Anpassungen vornehme, werde ich diesen Code aktualisieren.
quelle
!"#$%&'()*+,-./:;<=>?@{|}~
oder andere Formen wie/
SOLIDUS und `⁄` FRACTION SLASH, die problemlos direkt in Dateinamen verwendet werden könnenIch denke, das Problem ist, dass Sie zuerst
Path.GetDirectoryName
die schlechte Zeichenfolge aufrufen . Wenn dies Zeichen ohne Dateinamen enthält, kann .Net nicht erkennen, welche Teile der Zeichenfolge Verzeichnisse und Überwürfe sind. Sie müssen Zeichenfolgenvergleiche durchführen.Angenommen, nur der Dateiname ist schlecht, nicht der gesamte Pfad, versuchen Sie Folgendes:
quelle
Damit war ich in der Vergangenheit erfolgreich.
Schön, kurz und statisch :-)
quelle
Hier gibt es viele funktionierende Lösungen. Der Vollständigkeit halber ist hier ein Ansatz, der keinen regulären Ausdruck verwendet, sondern LINQ:
Es ist auch eine sehr kurze Lösung;)
quelle
Hier ist eine effiziente Methode zum verzögerten Laden von Erweiterungen, die auf Andres Code basiert:
quelle
Ihr Code wäre sauberer, wenn Sie das Verzeichnis und den Dateinamen zusammenfügen und das bereinigen würden, anstatt sie unabhängig voneinander zu bereinigen. Um das: zu bereinigen, nehmen Sie einfach das 2. Zeichen in der Zeichenfolge. Wenn es gleich "replacechar" ist, ersetzen Sie es durch einen Doppelpunkt. Da diese App für Ihren eigenen Gebrauch bestimmt ist, sollte eine solche Lösung vollkommen ausreichen.
quelle
quelle