Найпростіший спосіб перевірити, чи є довільний рядок дійсним іменем файлу


79

У моїй програмі користувач може ввести ім'я файлу. Перед обробкою я хотів би перевірити, чи є вхідний рядок дійсним іменем файлу в Windows Vista.

Який найпростіший спосіб це зробити?

За дійсним я посилаюся на юридичні та неіснуючі


Коли ви говорите дійсне ім'я файлу, ви маєте на увазі факт існування файлу чи запитуєте, чи дозволить це ім'я операційна система?
Jesse McCulloch

4
Діє, як у (а) існуючих, (б) юридичних чи (в) юридичних та неіснуючих?
Ентоні Пеграм

Прямо, я мав це пояснити. Це повинно бути (c) законним та неіснуючим
RoflcoptrException

4
@roflcopter: Під час створення файлу потрібно просто обробляти помилки. Будь-яка операція з файловою системою, яка включає перевірку існування, вже потенційно застаріла на момент повернення, оскільки файлова система є глобальним спільним ресурсом.
Ben Voigt

1
@Roflcoptr: файл із точно такою ж назвою створюється між моментом перевірки дійсності та / або існування, і моментом, коли ви насправді намагаєтесь створити його, не слід вважати звичайним потоком програми. Вам слід перевірити, що файл не існує, але коли ви насправді створюєте файл, ці знання вже давні і їх слід вважати лише освіченим здогадом. Це, ймовірно, все ще буде правдою, але це не гарантується .
Фредрік Морк

Відповіді:


125

Перевірте , чи правильно чи filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0й!File.Exists(Path.Combine(someFolder, filename))


1
Перевірте відповідь Філа Хунта; виявляється, що InvalidPathChars є застарілим API, і замість цього слід використовувати GetInvalidFileNameChars ().
GendoIkari

3
<quote> Масив, що повертається цим методом, не гарантовано міститиме повний набір символів, які є неприпустимими в іменах файлів та каталогів. </quote> Також ця властивість застаріла.
Бен Войгт,

4
зустрічний приклад: "http://www.microsoft.com/"здає тест, але не є дійсним ім’ям файлу, так само"::::"
Бен Войгт,

3
Інші зустрічні приклади: "" недійсний, а новий рядок ('x', 1024) теж недійсний.
Расмус Фабер,

2
@shellster Ви можете перейменувати файл у ".txt" у провіднику Windows, сказавши провіднику перейменувати файл у ".txt.". Просто підказка (або ".txt ........" теж буде працювати).
Robert McKee

37

Перевірка проти GetInvalidFileNameChars():

var isValid = !string.IsNullOrEmpty(fileName) &&
              fileName.IndexOfAny(Path.GetInvalidFileNameChars()) < 0 &&
              !File.Exists(Path.Combine(sourceFolder, fileName));

2
зустрічний приклад: "http://www.microsoft.com/"здає тест, але не є дійсним ім'ям файлу, так само"::::"
Бен Войгт,

1
@Ben Voigt: Ви праві, що ::::неправильно було визнано дійсним. Я виправив відповідь, вказавши < 0замість == 0.
Філ Хант,

1
О, я щойно помітив, що ти використовуєш GetInvalidFileNameChars, а не GetInvalidPathCharsяк SLaks. Поки це тест лише для імені файлу, а не для імені файлу із шляхом, це буде нормально.
Ben Voigt

@Ben Voigt: Оскільки ОП запитувало про перевірку імен файлів та шляхів лише неявно для підтвердження неіснуючого файлу, я використав GetInvalidFileNameChars:-)
Філ Хант,

11

Якщо файл буде створено, вам слід використати діалогове вікно файлу, щоб вказати шлях до каталогу. Існує короткий список заборонених символів для імен файлів.

Єдиний справді надійний спосіб визначити, чи прийнятно ім’я файлу, - це спробувати його. Дозволи - це болота.


Діалогове вікно файлу - це червоний оселедець, але +1 для "єдино справді надійного способу ... це спробувати".
Ben Voigt

1
Домовились. Навіть якщо ім'я файлу не існує і не містить незаконних символів, існує низка причин, чому файл не може бути створений, найбільш очевидною є відсутність дозволу на створення каталогу.
Боб Кауфман,

Бувають випадки, коли вам потрібно зберегти невідомий шлях, але ви не хочете, щоб користувач вибрав точний шлях. У цих випадках діалогове вікно файлу неможливо.
Джош Ное

2

Я використовую це:

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;
}

Повинен дбати про все, крім зарезервованих імен, дозволів та обмежень довжини. Це приймає як відносні, так і абсолютні імена файлів.


0

Це лише ідея. Слід заповнити список винятків:

public static bool IsValidFilename(string filename)
{
    try
    {
        File.OpenRead(filename).Close();
    }
    catch (ArgumentException) { return false; }
    catch (Exception) { }
    return true;
}

Що робити, якщо файл ще не існує?
Mike Cheel

@MikeCheel Код повертає значення false, лише якщо викинуто виняток аргументу. Цей виняток видається лише в тому випадку, якщо ім'я файлу недійсне.
Бурак
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.