2009-01-07 3 views
112

Gibt es eine Methode im Namespace System.IO, die die Gültigkeit eines Dateinamens überprüft?In C# überprüfen, ob der Dateiname * möglicherweise * gültig ist (nicht dass er existiert)

Zum Beispiel würde C:\foo\bar validieren und :"~-* nicht

Oder ein wenig komplizierter ist X:\foo\bar zu validieren wäre ein X: Laufwerk auf dem System gibt es, aber es sonst nicht.

Ich denke, ich könnte eine solche Methode selbst schreiben, aber ich bin mehr interessiert an einem eingebauten.

+0

Besteht die "nicht, dass es beendet wird", die Validierung der Ordner vorhanden oder nicht? Was sind die Grenzen des Schecks? Dass das Laufwerk existiert und dass alle Zeichen gültig sind? – BenAlabaster

Antwort

33

Sie können eine Liste von ungültigen Zeichen von Path.GetInvalidPathChars erhalten und GetInvalidFileNameChars wie in this question.

diskutiert Wie jberger erwähnt, gibt es einige andere Zeichen, die von dieser Methode in der Antwort enthalten sind. Für viel mehr Details der Windows-Plattform, werfen Sie einen Blick auf Naming Files, Paths and Namespaces auf MSDN,

Als Micah points out gibt es Directory.GetLogicalDrives eine Liste der gültigen Laufwerke zu bekommen.

+4

"Das Array, das von dieser Methode zurückgegeben wird, enthält nicht garantiert ** den vollständigen Zeichensatz, der in Datei- und Verzeichnisnamen ungültig ist." [Hinweise] (http://msdn.microsoft.com/en-us/library/system.io.path.getinvalidfilenamechars.aspx) –

+0

Lassen Sie mich darauf hinweisen. Die Charaktere allein reichen nicht aus, um zu wissen, dass sie gültig sind. Zum Beispiel: ist Null oder ein Mal gültig, aber es ist NICHT immer das zweite Zeichen in der Zeichenfolge, wenn es existiert! –

+0

Das ist nicht korrekt. Bestimmte Namen sind ebenfalls verboten, nicht nur bestimmte Zeichen. –

79

Nur tun;

System.IO.FileInfo fi = null; 
try { 
    fi = new System.IO.FileInfo(fileName); 
} 
catch (ArgumentException) { } 
catch (System.IO.PathTooLongException) { } 
catch (NotSupportedException) { } 
if (ReferenceEquals(fi, null)) { 
    // file name is not valid 
} else { 
    // file name is valid... May check for existence by calling fi.Exists. 
} 

für die Erstellung einer FileInfo Instanz die Datei muss nicht existieren.

+15

Seien Sie vorsichtig mit FileInfo. Eine beliebige Zeichenfolge, auch wenn es nur ein einzelner Buchstabe ist, ist ein gültiges Argument im Konstruktor, aber wenn Sie einfach FileInfo (pathTheuserEntered) ausprobieren, wird FileInfo davon ausgehen, dass die Datei relativ zum aktuellen Arbeitsverzeichnis ist, was möglicherweise nicht Ihren Vorstellungen entspricht. – Echilon

+1

Ich verbesserte diese Lösung mit bOk = System.IO.Path.IsPathRooted (fileName); statt bOk = wahr; – jing

+5

Dies fängt keinen Dateinamen mit '/' ein, der nicht gültig ist. – Marc

2

Verwenden Sie die statische GetInvalidFileNameChars method auf der Path class in System.IO namespace, um festzustellen, welche Zeichen in einem Dateinamen unzulässig sind.

Um dies in einem Pfad zu tun, rufen Sie die statische auf der gleichen Klasse.

Um festzustellen, ob die Wurzel eines Pfad gültig ist, können Sie die statische GetPathRoot method auf der Path Klasse nennen würde die Wurzel zu erhalten, verwenden Sie dann den Directory class zu bestimmen, ob es gültig ist. Dann können Sie den Rest des Pfades normal validieren.

+1

"Das von dieser Methode zurückgegebene Array enthält nicht die ** vollständigen ** Zeichen, die in Datei- und Verzeichnisnamen ungültig sind." [Hinweise] (http://msdn.microsoft.com/en-us/library/system.io.path.getinvalidfilenamechars.aspx) –

+0

Erweitern, was RobertP oben gesagt hat ... Die Verwendung von GetInvalidPathChars in und für sich ist nicht genau korrekte Methode zum Testen der Gültigkeit einer Zeichenfolge, die einen Pfad darstellt. Diese Methode gibt die 'Steuerzeichen' zurück und "><| bedeutet, dass diese Zeichenfolge (abzüglich der einschließenden doppelten Anführungszeichen) gültig ist" C: \ Ordner1 \ Ordner * 2 \ Fol: der3 ". Öffnen Sie nun Windows Explorer oder eine Befehlskonsole und versuchen Sie, diese Ordnerstruktur zu erstellen und lassen Sie mich wissen, was passiert ... Sie müssen den Pfad in seine Komponenten zerlegen und auf einen gültigen Volume-Bezeichner testen und jede Verzeichnis-Komponente als gültiger Dateiname testen – PMBottas

5

Auch wenn der Dateiname gültig ist, möchten Sie vielleicht immer noch touch, um sicher zu sein, dass der Benutzer Schreibberechtigung hat.

Wenn Sie nicht die Festplatte mit Hunderten von Dateien in kurzer Zeit schlagen wird, denke ich, eine leere Datei erstellen ist ein vernünftiger Ansatz.

Wenn Sie wirklich etwas leichteres wollen, zum Beispiel nur nach ungültigen Zeichen suchen, dann vergleichen Sie Ihren Dateinamen mit Path.GetInvalidFileNameChars().

0

Wahrscheinlich der Bast Weg ist eine benutzerdefinierte Methode Mischen eine Kombination von regex und kleinem Blick auf Ihrem Dateisystem zu bauen (um die Antriebe zu sehen, zum Beispiel)

1

Ich weiß nicht von irgendetwas von dem aus Box, die nur das alles für Sie validieren kann, aber die Path Klasse in .NET kann Ihnen enorm helfen.

Für den Anfang hat:

char[] invalidChars = Path.GetInvalidFileNameChars(); //returns invalid charachters 

oder:

Path.GetPathRoot(string); // will return the root. 
2

Mehrere der System.IO.Path Methoden Ausnahmen auslösen, wenn der Pfad oder Dateiname ist ungültig:

  • Path.IsPathRooted()
  • Path.GetFileName()

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

+0

Dies scheint nicht wahr zu sein zumindest in Mono (zB in Unity). Ich benutze einen falschen Pfad von "Bogus \\ Invalid!/No: Solch? Datei! * @ #!", und IsPathRooted gibt true zurück, GetFileName gibt den Teil nach dem Schrägstrich zurück , und FileInfo kann keine Exception auslösen (obwohl das Aufrufen von GetDirectories im Verzeichnis eine Exception auslöst, ist das vielleicht die Antwort in meinem Fall.) –

+0

Das funktioniert nicht Path.GetFileName ("* xxx?") gibt "* xxx?" ohne Ausnahme zurück Ion. Vergessen Sie auch nicht reservierte Dateinamen, die für neue Dateien falsch sind. In Windows sind das "prn", "con" usw. – epox

+0

Diese Antwort ist falsch. –

8

Es gibt mehrere Methoden, die Sie könnten, die im System.IO Namespace existieren verwenden:

Directory.GetLogicalDrives() // Returns an array of strings like "c:\" 
Path.GetInvalidFileNameChars() // Returns an array of characters that cannot be used in a file name 
Path.GetInvalidPathChars() // Returns an array of characters that cannot be used in a path. 

Wie vorgeschlagen, dass Sie könnte dann dies tun:

bool IsValidFilename(string testName) { 
    string regexString = "[" + Regex.Escape(Path.GetInvalidPathChars()) + "]"; 
    Regex containsABadCharacter = new Regex(regexString); 
    if (containsABadCharacter.IsMatch(testName)) { 
     return false; 
    } 

    // Check for drive 
    string pathRoot = Path.GetPathRoot(testName); 
    if (Directory.GetLogicalDrives().Contains(pathRoot)) { 
     // etc 
    } 

    // other checks for UNC, drive-path format, etc 

    return true; 
} 
+17

Nicht zu votieren, aber Sie sollten wirklich Kredit geben, wenn Sie Beispielcode von anderen Leuten verwenden, besonders wenn es nicht wirklich korrekt ist. http://stackoverflow.com/questions/62771/how-check-if-given-string-is-legal-allowed-file-name-under-windows#62855 –

+3

"regexString" sollte eher wie folgt aussehen: string regexStringPath = "[" + Regex.Escape (neue Zeichenfolge (System.IO.Path.GetInvalidPathChars())) + "]"; – panako

+0

Was ist mit '@" C: \\ Windows "' (_indeed_ mit Doppel-Backslash)? Der Explorer sagt, dass es kein gültiger Pfad ist, aber Sie überprüfen dies nicht. – KnorxThieus

1

Diese erhalten Sie die Laufwerke an der Maschine:

System.IO.DriveInfo.GetDrives() 

Diese beiden Methoden werden Sie die schlechten Zeichen erhalten zu überprüfen:

System.IO.Path.GetInvalidFileNameChars(); 
System.IO.Path.GetInvalidPathChars(); 
1

Ich habe Glück gehabt mit regulären Ausdrücken wie andere gezeigt haben.

Eine Sache zu beachten ist, dass Windows zumindest einige Dateinamen verbietet, die sonst legale Zeichen enthalten. Ein paar kommen in den Sinn: com, nul, prn.

Ich habe es jetzt nicht bei mir, aber ich habe eine Regex, die diesen Dateinamen berücksichtigt. Wenn du willst, kann ich es posten, ansonsten bin ich mir sicher, dass du es genauso finden kannst wie ich: Google.

-Jay

7

Sie könnten die System.Uri Klasse nutzen. Die Uri-Klasse ist nicht nur für Web-URLs nützlich, sondern auch für Dateisystempfade. Verwenden Sie die Uri.TryCreate-Methode, um zu ermitteln, ob der Pfad gerootet ist, und verwenden Sie dann die IsLoopback-Eigenschaft, um festzustellen, ob die Uri auf den lokalen Computer verweist.

Hier ist eine einfache Methode, die bestimmt, ob eine Zeichenfolge ein gültiger, lokaler und gerooteter Dateipfad ist.

public bool IsPathValidRootedLocal(String pathString) { 
    Uri pathUri; 
    Boolean isValidUri = Uri.TryCreate(pathString, UriKind.Absolute, out pathUri); 
    return isValidUri && pathUri != null && pathUri.IsLoopback; 
} 

Ich bin zuversichtlich, dass dies funktioniert.

+0

Sie sollten auch überprüfen, ob 'Uri.Schema' eine Datei ist. – drowa

+1

Auch Dinge wie 'file: /// a' würden von Ihrer Methode als gültiger Pfad akzeptiert werden. – drowa

+0

Funktioniert auch nicht, wenn Sie ein Fragezeichen am Ende haben. 'C: \\ foo \\ bar ??' –

0

Denken Sie es zu spät ist zu beantworten, aber ... :) bei Pfad mit Volume-Namen Sie so etwas schreiben könnte:

using System; 
using System.Linq; 
using System.IO; 

// ... 

var drives = Environment.GetLogicalDrives(); 
var invalidChars = Regex.Replace(new string(Path.GetInvalidFileNameChars()), "[\\\\/]", ""); 
var drive = drives.FirstOrDefault(d => filePath.StartsWith(d)); 
if (drive != null) { 
    var fileDirPath = filePath.Substring(drive.Length); 
    if (0 < fileDirPath.Length) { 
     if (fileDirPath.IndexOfAny(invalidChars.ToCharArray()) == -1) { 
      if (Path.Combine(drive, fileDirPath) != drive) { 
       // path correct and we can proceed 
      } 
     } 
    } 
} 
3

dachte, ich würde eine Lösung poste ich zusammen aus Bits gepflasterten von Antworten fand ich nach der Suche nach einer robusten Lösung für das gleiche Problem. Hoffentlich hilft es jemand anderem.

using System; 
using System.IO; 
//.. 

     public static bool ValidateFilePath(string path,bool RequireDirectory,bool IncludeFileName,bool RequireFileName=false) 
    { 
     if (string.IsNullOrEmpty(path)) {return false;} 
     string root = null; ; 
     string directory=null; 
     string filename=null; 
     try 
     { 
      //throw ArgumentException - The path parameter contains invalid characters, is empty, or contains only white spaces. 
      root = Path.GetPathRoot(path); 
      //throw ArgumentException - path contains one or more of the invalid characters defined in GetInvalidPathChars. 
      // -or- String.Empty was passed to path. 
      directory = Path.GetDirectoryName(path); 
      //path contains one or more of the invalid characters defined in GetInvalidPathChars 
      if (IncludeFileName) { filename = Path.GetFileName(path); } 
     } 
     catch (ArgumentException) 
     { 
      return false; 
     } 
     //null if path is null, or an empty string if path does not contain root directory information 
     if (String.IsNullOrEmpty(root)){return false;} 
     //null if path denotes a root directory or is null. Returns String.Empty if path does not contain directory information 
     if (String.IsNullOrEmpty(directory)) { return false; } 
     if (RequireFileName) 
     { 
      //f the last character of path is a directory or volume separator character, this method returns String.Empty 
      if (String.IsNullOrEmpty(filename)) { return false; } 
      //check for illegal chars in filename 
      if (filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0){ return false;} 
     } 
     return true; 
    } 
1

Probieren Sie diese Methode, die versuchen würde, für alle möglichen Ausnahmen Szenarien zu decken.Es würde für fast alle Windows-bezogenen Pfade funktionieren.

/// <summary> 
/// Validate the Path. If path is relative append the path to the project directory by default. 
/// </summary> 
/// <param name="path">Path to validate</param> 
/// <param name="RelativePath">Relative path</param> 
/// <param name="Extension">If want to check for File Path</param> 
/// <returns></returns> 
private static bool ValidateDllPath(ref string path, string RelativePath = "", string Extension = "") { 
    // Check if it contains any Invalid Characters. 
    if (path.IndexOfAny(Path.GetInvalidPathChars()) == -1) { 
     try { 
      // If path is relative take %IGXLROOT% as the base directory 
      if (!Path.IsPathRooted(path)) { 
       if (string.IsNullOrEmpty(RelativePath)) { 
        // Exceptions handled by Path.GetFullPath 
        // ArgumentException path is a zero-length string, contains only white space, or contains one or more of the invalid characters defined in GetInvalidPathChars. -or- The system could not retrieve the absolute path. 
        // 
        // SecurityException The caller does not have the required permissions. 
        // 
        // ArgumentNullException path is null. 
        // 
        // NotSupportedException path contains a colon (":") that is not part of a volume identifier (for example, "c:\"). 
        // PathTooLongException The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 

        // RelativePath is not passed so we would take the project path 
        path = Path.GetFullPath(RelativePath); 

       } else { 
        // Make sure the path is relative to the RelativePath and not our project directory 
        path = Path.Combine(RelativePath, path); 
       } 
      } 

      // Exceptions from FileInfo Constructor: 
      // System.ArgumentNullException: 
      //  fileName is null. 
      // 
      // System.Security.SecurityException: 
      //  The caller does not have the required permission. 
      // 
      // System.ArgumentException: 
      //  The file name is empty, contains only white spaces, or contains invalid characters. 
      // 
      // System.IO.PathTooLongException: 
      //  The specified path, file name, or both exceed the system-defined maximum 
      //  length. For example, on Windows-based platforms, paths must be less than 
      //  248 characters, and file names must be less than 260 characters. 
      // 
      // System.NotSupportedException: 
      //  fileName contains a colon (:) in the middle of the string. 
      FileInfo fileInfo = new FileInfo(path); 

      // Exceptions using FileInfo.Length: 
      // System.IO.IOException: 
      //  System.IO.FileSystemInfo.Refresh() cannot update the state of the file or 
      //  directory. 
      // 
      // System.IO.FileNotFoundException: 
      //  The file does not exist.-or- The Length property is called for a directory. 
      bool throwEx = fileInfo.Length == -1; 

      // Exceptions using FileInfo.IsReadOnly: 
      // System.UnauthorizedAccessException: 
      //  Access to fileName is denied. 
      //  The file described by the current System.IO.FileInfo object is read-only.-or- 
      //  This operation is not supported on the current platform.-or- The caller does 
      //  not have the required permission. 
      throwEx = fileInfo.IsReadOnly; 

      if (!string.IsNullOrEmpty(Extension)) { 
       // Validate the Extension of the file. 
       if (Path.GetExtension(path).Equals(Extension, StringComparison.InvariantCultureIgnoreCase)) { 
        // Trim the Library Path 
        path = path.Trim(); 
        return true; 
       } else { 
        return false; 
       } 
      } else { 
       return true; 

      } 
     } catch (ArgumentNullException) { 
      // System.ArgumentNullException: 
      //  fileName is null. 
     } catch (System.Security.SecurityException) { 
      // System.Security.SecurityException: 
      //  The caller does not have the required permission. 
     } catch (ArgumentException) { 
      // System.ArgumentException: 
      //  The file name is empty, contains only white spaces, or contains invalid characters. 
     } catch (UnauthorizedAccessException) { 
      // System.UnauthorizedAccessException: 
      //  Access to fileName is denied. 
     } catch (PathTooLongException) { 
      // System.IO.PathTooLongException: 
      //  The specified path, file name, or both exceed the system-defined maximum 
      //  length. For example, on Windows-based platforms, paths must be less than 
      //  248 characters, and file names must be less than 260 characters. 
     } catch (NotSupportedException) { 
      // System.NotSupportedException: 
      //  fileName contains a colon (:) in the middle of the string. 
     } catch (FileNotFoundException) { 
      // System.FileNotFoundException 
      // The exception that is thrown when an attempt to access a file that does not 
      // exist on disk fails. 
     } catch (IOException) { 
      // System.IO.IOException: 
      //  An I/O error occurred while opening the file. 
     } catch (Exception) { 
      // Unknown Exception. Might be due to wrong case or nulll checks. 
     } 
    } else { 
     // Path contains invalid characters 
    } 
    return false; 
} 
Verwandte Themen