C # Sanitize Dateiname
Ich vor kurzem haben sich ein Haufen MP3s von verschiedenen Standorten in ein repository. Ich hatte schon den Bau der neuen Dateinamen aus den ID3-tags (danke, TagLib-Sharp!), und ich bemerkte, dass ich immer ein System.NotSupportedException
:
"Der angegebene Pfad das format wird nicht unterstützt."
Diese wurde erzeugt, indem entweder File.Copy()
oder Directory.CreateDirectory()
.
Dauerte es nicht lange, zu erkennen, dass meine Datei-Namen benötigt werden saniert. Also Tat ich das naheliegende 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, fuhr ich Fort, um Ausnahmen. Es stellte sich heraus, dass ':' ist nicht in der Menge der Path.GetInvalidPathChars()
weil es ist gültig in einem Pfad root. Ich nehme an, das macht Sinn - aber das ist ein ziemlich verbreitetes problem. Hat jemand ein paar kurzen code, desinfiziert Pfad? Die gründlichste, die ich mir ausgedacht habe, aber es fühlt sich an wie es ist wahrscheinlich übertrieben.
//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 wäre sehr geschätzt werden.
InformationsquelleAutor der Frage Jason Sundram | 2008-11-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Bereinigen einer Datei-Namen, die Sie tun können, diese
InformationsquelleAutor der Antwort Andre
Eine kürzere Lösung:
InformationsquelleAutor der Antwort DenNukem
Basierend auf Andre ausgezeichnete Antwort, aber unter Berücksichtigung von Spud ' s Kommentar zu reservierten Worten, ich habe diese version:
Und dies sind meine unit-tests
InformationsquelleAutor der Antwort fiat
InformationsquelleAutor der Antwort data
Ich bin mit der
System.IO.Path.GetInvalidFileNameChars()
Methode zu überprüfen, ungültige Zeichen und ich habe keine Probleme.Ich bin mit dem folgenden code:
InformationsquelleAutor der Antwort André Leal
Wollte ich behalten, die Charaktere in irgendeiner Weise, auch nicht gerade einfach ersetzen Sie das Zeichen mit einem Unterstrich.
Einer Weise, die ich dachte, war, ersetzen Sie die Zeichen mit ähnlich aussehenden Zeichen, die (in meiner situation), ist es unwahrscheinlich, verwendet werden, als reguläre Zeichen. Also nahm ich die Liste der ungültigen Zeichen gefunden und look-a-likes.
Sind die folgenden Funktionen zum codieren und decodieren mit den look-a-likes.
Diesen code nicht enthalten, eine vollständige Liste für alle vom System.IO.Pfad.GetInvalidFileNameChars() Zeichen. So ist es bis zu Ihnen zu verlängern oder verwenden Sie den Unterstrich Ersatz für jedes Verbleibende Zeichen.
Können Sie Ihren eigenen look-a-likes. Ich benutzt die Zeichentabelle-Anwendung in windows zu wählen mine
%windir%\system32\charmap.exe
Wie ich Anpassungen vornehmen, durch die Entdeckung, ich werde aktualisieren diesen code.
InformationsquelleAutor der Antwort Valamas
Ich denke, das problem ist, dass Sie zuerst anrufen
Path.GetDirectoryName
auf die schlechte saite. Wenn dies nicht mit dem Namen Zeichen, .Net kann nicht sagen, welche Teile des Strings sind Verzeichnisse und wirft. Sie haben zu tun, sind string-Vergleiche.Vorausgesetzt, es ist nur der Dateiname, das ist schlecht, nicht der gesamte Pfad, versuchen Sie dies:
InformationsquelleAutor der Antwort Dour High Arch
Ich habe Erfolg damit in der Vergangenheit.
Schönen, kurzen und statischen 🙂
InformationsquelleAutor der Antwort Helix 88
Hier ist eine effiziente lazy loading extension-Methode basiert auf Andre ' s code:
InformationsquelleAutor der Antwort Lone Coder
Würde der code sauberer, wenn Sie angehängt wird die Verzeichnis-und Dateinamen zusammen und saniert, anstatt Hygienisierung von Ihnen unabhängig. Für die Desinfektion entfernt ist :, nehmen Sie nur das 2. Zeichen im string. Wenn es gleich "replacechar", ersetzen Sie es mit einem Doppelpunkt. Da diese app ist für Ihren eigenen Gebrauch, eine solche Lösung sollte völlig ausreichend sein.
InformationsquelleAutor der Antwort Brian
InformationsquelleAutor der Antwort Ralf