Определите через C #, является ли строка допустимым путем к файлу - PullRequest
44 голосов
/ 18 июня 2010

Я хотел бы знать, как определить, является ли строка допустимым путем к файлу.

Путь к файлу может или может не существовать.

Ответы [ 10 ]

53 голосов
/ 18 июня 2010

Вы можете использовать конструктор FileInfo .Он выдаст исключение ArgumentException, если «Имя файла пустое, содержит только пробелы или содержит недопустимые символы».Он также может генерировать исключение SecurityException или UnauthorizedAccessException, которое, я думаю, можно игнорировать, если вас беспокоит только формат.

Другой вариант - проверить Path.GetInvalidPathChars напрямую.Например:

boolean possiblePath = pathString.IndexOfAny(Path.GetInvalidPathChars()) == -1;
22 голосов
/ 18 июня 2010

Точная проверка формата строки пути на 100% довольно сложна, поскольку она будет зависеть от файловой системы, в которой он используется (и сетевых протоколов, если она не на том же компьютере).

Даже в пределахWindows или даже NTFS - это не просто, так как он все еще зависит от API .NET, который используется в фоновом режиме для взаимодействия с ядром.

И так как большинство файловых систем сегодня поддерживают Unicode, может также понадобиться проверить всеправила для правильно закодированного юникода, нормализации и т. д. и т. д.

Я бы сделал только некоторые базовые проверки, а затем правильно обработал исключения после использования пути.Для возможных правил см .:

8 голосов
/ 18 июня 2010

Вот некоторые вещи, которые вы можете использовать:

  • , чтобы проверить правильность диска (например, на одном компьютере диск X: \ существует, но не на вашем): используйте Path.IsPathRootedчтобы увидеть, не является ли это относительным путем, а затем используйте диски из Environment.GetLogicalDrives(), чтобы проверить, содержит ли ваш путь один из допустимых дисков.
  • Чтобы проверить допустимые символы, у вас есть два метода: Path.GetInvalidFileNameChars() иPath.GetInvalidPathChars(), которые не полностью перекрываются.Вы также можете использовать Path.GetDirectoryName(path) и Path.GetFileName(fileName) со своим входным именем, которое вызовет исключение , если

Параметр пути содержит недопустимые символы, пуст,или содержит только пробелы.

3 голосов
/ 18 июня 2010

Вы не можете быть уверены, пока не попробуете создать этот файл.Возможно, путь верен, но настройки безопасности не позволят создать файл.Единственный экземпляр, который может сообщить вам, если путь REALLY valid - это операционная система, так почему бы вам не попытаться создать этот файл с перехватом IOException, который указывает, что он недействителен?По моему скромному мнению, это подход: предположите, что ввод действителен, используйте его и поймайте IOException, когда он не действителен.

2 голосов
/ 12 февраля 2015

Попробуйте этот метод, который будет пытаться охватить все возможные сценарии исключений. Это будет работать почти для всех путей, связанных с Windows.

/// <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;
}
2 голосов
/ 18 июня 2010

Вы пробовали регулярные выражения?

^([a-zA-Z]\:)(\\[^\\/:*?<>"|]*(?<![ ]))*(\.[a-zA-Z]{2,6})$

должно работать

1 голос
/ 31 октября 2016
Regex driveCheck = new Regex(@"^[a-zA-Z]:\\$");
      if (string.IsNullOrWhiteSpace(path) || path.Length < 3)
      {
        return false;
      }

      if (!driveCheck.IsMatch(path.Substring(0, 3)))
      {
        return false;
      }
      string strTheseAreInvalidFileNameChars = new string(Path.GetInvalidPathChars());
      strTheseAreInvalidFileNameChars += @":/?*" + "\"";
      Regex containsABadCharacter = new Regex("[" + Regex.Escape(strTheseAreInvalidFileNameChars) + "]");
      if (containsABadCharacter.IsMatch(path.Substring(3, path.Length - 3)))
      {
        return false;
      }

      DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetFullPath(path));
      try
      {
        if (!directoryInfo.Exists)
        {
          directoryInfo.Create();
        }
      }
      catch (Exception ex)
      {
        if (Log.IsErrorEnabled)
        {
          Log.Error(ex.Message);
        }
        return false;
      }`enter code here`

      return true;
    }
0 голосов
/ 24 октября 2012

Вы можете просто использовать Path.Combine () внутри оператора try catch:

string path = @" your path ";
try
{
    Path.Combine(path);
}
catch
{
    MessageBox.Show("Invalid path");
}

Edit: Обратите внимание, что эта функция не выдает исключение, если путь содержит символы подстановки('*' и '?'), поскольку они могут использоваться в строках поиска.

0 голосов
/ 18 июня 2010

Статический класс System.IO.Path может делать то, что вы просите.

0 голосов
/ 18 июня 2010

Я нашел это на regexlib.com (http://regexlib.com/REDetails.aspx?regexp_id=345) от Дмитрия Борисова.

"Валидатор имени файла. Проверяет как UNC (\ server \ share \ file), так и обычный путь MS (c:\ file) "

^(([a-zA-Z]:|\\)\\)?(((\.)|(\.\.)|([^\\/:\*\?"\|<>\. ](([^\\/:\*\?"\|<>\. ])|([^\\/:\*\?"\|<>]*[^\\/:\*\?"\|<>\. ]))?))\\)*[^\\/:\*\?"\|<>\. ](([^\\/:\*\?"\|<>\. ])|([^\\/:\*\?"\|<>]*[^\\/:\*\?"\|<>\. ]))?$

Запустите его с помощью Regex.IsMatch, и вы получите логическое значение, указывающее, действительно ли оно допустимо или нет. Я думаю, что регулярные выражения - это путь, поскольку файл может не существовать.

...