Gibt es eine Methode im System.IO-Namespace, die die Gültigkeit eines Dateinamens überprüft?
Zum Beispiel würde C:\foo\bar
Validieren und :"~-*
Nicht
Oder ein bisschen kniffliger: X:\foo\bar
Würde bestätigen, dass ein X:
- Laufwerk im System vorhanden ist, würde dies aber nicht tun.
Ich nehme an, ich könnte eine solche Methode selbst schreiben, aber ich bin mehr an einer eingebauten interessiert.
Mach einfach;
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.
}
Zum Erstellen einer FileInfo
-Instanz muss die Datei nicht vorhanden sein.
Sie können eine Liste ungültiger Zeichen von Path.GetInvalidPathChars und GetInvalidFileNameChars abrufen, wie in diese Frage erläutert
Wie von jberger bemerkt, gibt es einige andere Zeichen, die in der Antwort von dieser Methode nicht enthalten sind. Weitere Informationen zur Windows-Plattform finden Sie unter Benennen von Dateien, Pfaden und Namespaces auf MSDN,
Wie Micah weist darauf hin , gibt es Directory.GetLogicalDrives , um eine Liste der gültigen Laufwerke abzurufen.
Sie können die System.Uri-Klasse verwenden. Die Uri-Klasse ist nicht nur für Web-URLs nützlich, sondern verarbeitet auch Dateisystempfade. Verwenden Sie die Uri.TryCreate-Methode, um festzustellen, ob der Pfad verwurzelt ist, und verwenden Sie dann die IsLoopback-Eigenschaft, um festzustellen, ob der Uri auf den lokalen Computer verweist.
Hier ist eine einfache Methode, die feststellt, ob eine Zeichenfolge ein gültiger, lokaler und verwurzelter 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 funktionieren wird.
Es gibt verschiedene Methoden, die Sie verwenden können, die in der System.IO
Namespace:
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, könnten Sie dies dann 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;
}
Ich dachte, ich würde eine Lösung veröffentlichen, die ich aus vielen Antworten zusammengestellt habe, nachdem ich nach einer zuverlässigen Lösung für dasselbe Problem gesucht hatte. 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)
{
// if 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;
}
Auch wenn der Dateiname gültig ist, möchten Sie ihn möglicherweise trotzdem touch
, um sicherzustellen, dass der Benutzer über die Berechtigung zum Schreiben verfügt.
Wenn Sie die Festplatte in kurzer Zeit nicht mit Hunderten von Dateien überhäufen, halte ich das Erstellen einer leeren Datei für einen vernünftigen Ansatz.
Wenn Sie wirklich etwas Leichteres wünschen, beispielsweise nur nach ungültigen Zeichen suchen, vergleichen Sie Ihren Dateinamen mit Path.GetInvalidFileNameChars ().
Probieren Sie diese Methode aus, um alle möglichen Ausnahmeszenarien abzudecken. 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;
}
Verwenden Sie die statische GetInvalidFileNameChars
-Methode für die Path
-Klasse in der System.IO
Namespace um festzustellen, welche Zeichen in einem Dateinamen unzulässig sind.
Rufen Sie dazu in einem Pfad die statische GetInvalidPathChars
-Methode für dieselbe Klasse auf.
Um festzustellen, ob die Wurzel eines Pfades gültig ist, rufen Sie die statische GetPathRoot
-Methode für die Path
-Klasse auf, um die Wurzel abzurufen, und verwenden Sie dann die Directory
class um festzustellen, ob es gültig ist. Dann können Sie den Rest des Pfades normal validieren.
Einige der System.IO.Path-Methoden lösen Ausnahmen aus, wenn der Pfad oder Dateiname ungültig ist:
http://msdn.Microsoft.com/en-us/library/system.io.path_methods.aspx
Ich hatte Glück mit regulären Ausdrücken, wie andere gezeigt haben.
Beachten Sie, dass Windows zumindest einige Dateinamen verbietet, die ansonsten ungültige Zeichen enthalten. Ein paar fallen mir ein: com, nul, prn.
Ich habe es jetzt nicht bei mir, aber ich habe einen regulären Ausdruck, der diese Dateinamen berücksichtigt. Wenn du willst, kann ich es posten, ansonsten findest du es sicher genauso wie ich: Google.
-Jay
Ich kenne nichts von der Stange, das all das für Sie validieren könnte, jedoch die Klasse Path
in .NET
kann dir enorm helfen.
Für den Anfang hat es:
char[] invalidChars = Path.GetInvalidFileNameChars(); //returns invalid charachters
oder:
Path.GetPathRoot(string); // will return the root.
Dadurch erhalten Sie die Laufwerke auf der Maschine:
System.IO.DriveInfo.GetDrives()
Mit diesen beiden Methoden können Sie die fehlerhaften Zeichen überprüfen:
System.IO.Path.GetInvalidFileNameChars();
System.IO.Path.GetInvalidPathChars();
Denke, es ist zu spät, um zu antworten, aber ... :) im Falle eines Pfades mit einem Datenträgernamen könnten Sie so etwas schreiben:
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
}
}
}
}
Wahrscheinlich ist es am besten, eine benutzerdefinierte Methode zu erstellen, die eine Kombination aus regulärem Ausdruck und kleiner Suche in Ihrem Dateisystem mischt (um beispielsweise die Laufwerke anzuzeigen).