Der einfachste Weg, um zu überprüfen, ob ein beliebiger String ein gültiger Dateiname ist

78

In meiner Anwendung kann der Benutzer einen Dateinamen eingeben. Vor der Verarbeitung möchte ich überprüfen, ob die Eingabezeichenfolge unter Windows Vista ein gültiger Dateiname ist.

Was ist der einfachste Weg, das zu tun?

Mit gültig beziehe ich mich auf legal und nicht existent

RoflcoptrException
quelle
Wenn Sie einen gültigen Dateinamen angeben, beziehen Sie sich auf die Tatsache, dass die Datei vorhanden ist, oder fragen Sie, ob der Name vom Betriebssystem zugelassen wird?
Jesse McCulloch
4
Gültig wie in (a) existierend, (b) legal oder (c) legal und nicht existent?
Anthony Pegram
Sry, ich hätte das klarstellen sollen. Es sollte (c) undicht sein und nicht existieren
RoflcoptrException
4
@roflcopter: Sie müssen einfach Fehler beim Erstellen der Datei behandeln. Jeder Dateisystemvorgang, bei dem eine Existenzprüfung durchgeführt wird, ist zum Zeitpunkt der Rückgabe möglicherweise bereits veraltet, da das Dateisystem eine globale gemeinsam genutzte Ressource ist.
Ben Voigt
1
@Roflcoptr: Eine Datei mit genau demselben Namen wird zwischen dem Zeitpunkt der Überprüfung der Gültigkeit und / oder Existenz und dem Zeitpunkt, zu dem Sie tatsächlich versuchen, sie zu erstellen, nicht als normaler Programmablauf angesehen. Sie sollten sicherstellen, dass die Datei nicht vorhanden ist. Wenn Sie die Datei jedoch tatsächlich erstellen, ist das Wissen bereits alt und sollte nur als fundierte Vermutung betrachtet werden. Es ist wahrscheinlich immer noch wahr, aber es ist nicht garantiert .
Fredrik Mörk

Antworten:

124

Überprüfen Sie, ob filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0und!File.Exists(Path.Combine(someFolder, filename))

SLaks
quelle
1
Überprüfen Sie jedoch die Antwort von Phil HUnt. Es scheint, dass InvalidPathChars eine veraltete API ist, und Sie sollten stattdessen GetInvalidFileNameChars () verwenden.
GendoIkari
3
<quote> Es wird nicht garantiert, dass das von dieser Methode zurückgegebene Array den vollständigen Satz von Zeichen enthält, die in Datei- und Verzeichnisnamen ungültig sind. </ quote> Außerdem ist diese Eigenschaft veraltet.
Ben Voigt
4
Gegenbeispiel: "http://www.microsoft.com/"Besteht Ihren Test, ist aber kein gültiger Dateiname, ebenso für"::::"
Ben Voigt
3
Weitere Gegenbeispiele: "" ist ungültig und der neue String ('x', 1024) ist ebenfalls nicht gültig.
Rasmus Faber
2
@shellster Sie können eine Datei im Windows Explorer in ".txt" umbenennen, indem Sie den Explorer anweisen, die Datei in ".txt" umzubenennen. Nur ein Tipp (oder ".txt ........" funktioniert auch).
Robert McKee
36

Prüfen Sie gegen GetInvalidFileNameChars():

var isValid = !string.IsNullOrEmpty(fileName) &&
              fileName.IndexOfAny(Path.GetInvalidFileNameChars()) < 0 &&
              !File.Exists(Path.Combine(sourceFolder, fileName));
Phil Hunt
quelle
2
Gegenbeispiel: "http://www.microsoft.com/"Besteht Ihren Test, ist aber kein gültiger Dateiname, ebenso für"::::"
Ben Voigt
1
@ Ben Voigt: Sie haben Recht, das ::::wurde fälschlicherweise als gültig angesehen. Ich habe die Antwort korrigiert, um < 0statt anzuzeigen == 0.
Phil Hunt
1
Oh, ich habe gerade bemerkt, dass du SLaks verwendest GetInvalidFileNameChars, nicht GetInvalidPathCharswie SLaks. Solange es sich nur um einen Test für den Dateinamen und nicht um einen Dateinamen mit Pfad handelt, ist dies in Ordnung.
Ben Voigt
@ Ben Voigt: Da das OP nach der Validierung von Dateinamen und Pfaden nur implizit gefragt hat, um die Nichtexistenz von Dateien zu validieren, habe ich verwendet GetInvalidFileNameChars:-)
Phil Hunt
11

Wenn die Datei erstellt werden soll, sollten Sie einen Dateidialog verwenden, um den Verzeichnispfad anzugeben. Es gibt eine kurze Liste unzulässiger Zeichen für Dateinamen.

Der einzig wirklich zuverlässige Weg, um festzustellen, ob ein Dateiname akzeptabel ist, besteht darin, ihn auszuprobieren. Berechtigungen sind ein Morast.

ddyer
quelle
Der Dateidialog ist ein roter Hering, aber +1 für "nur wirklich zuverlässiger Weg ... ist es, es zu versuchen".
Ben Voigt
1
Einverstanden. Selbst wenn der Dateiname nicht vorhanden ist und keine unzulässigen Zeichen enthält, gibt es eine Reihe von Gründen, warum die Datei nicht erstellt wird. Der offensichtlichste Grund ist das Fehlen einer Erstellungsberechtigung für das Verzeichnis.
Bob Kaufman
Es gibt Fälle, in denen Sie unter einem unbekannten Pfad speichern müssen, der Benutzer jedoch nicht den genauen Pfad auswählen soll. In diesen Fällen ist ein Dateidialog nicht möglich.
Josh Noe
2

Ich benutze das:

public static bool IsValidFileName(string name) {
    if(string.IsNullOrWhiteSpace(name)) return false;
    if(name.Length > 1 && name[1] == ':') {
        if(name.Length < 4 || name.ToLower()[0] < 'a' || name.ToLower()[0] > 'z' || name[2] != '\\') return false;
        name = name.Substring(3);
    }
    if(name.StartsWith("\\\\")) name = name.Substring(1);
    if(name.EndsWith("\\") || !name.Trim().Equals(name) || name.Contains("\\\\") ||
        name.IndexOfAny(Path.GetInvalidFileNameChars().Where(x=>x!='\\').ToArray()) >= 0) return false;
    return true;
}

Sollte sich um alles kümmern, außer um reservierte Namen, Berechtigungen und Längenbeschränkungen. Dies akzeptiert sowohl relative als auch absolute Dateinamen.

Duke Nukem
quelle
0

Dies ist nur eine Idee. Man sollte die Ausnahmeliste füllen:

public static bool IsValidFilename(string filename)
{
    try
    {
        File.OpenRead(filename).Close();
    }
    catch (ArgumentException) { return false; }
    catch (Exception) { }
    return true;
}
Bitter blau
quelle
Was ist, wenn die Datei noch nicht existiert?
Mike Cheel
@MikeCheel Der Code gibt nur dann false zurück, wenn eine Argumentausnahme ausgelöst wird. Diese Ausnahme wird nur ausgelöst, wenn der Dateiname ungültig ist.
Burak