Как я проверяю, является ли данная строка легальным именем / именем правильного файла в соответствии с Windows?

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

156
задан Luke Girvin 29 March 2018 в 13:26
поделиться

15 ответов

Можно получить список недопустимых символов от Path.GetInvalidPathChars и GetInvalidFileNameChars .

UPD: Видят предложение Steve Cooper о том, как использовать их в регулярном выражении.

UPD2: Примечание, что согласно разделу Remarks в MSDN "Массив, возвращенный из этого метода, как гарантируют, не будет содержать полный набор символов, которые недопустимы в именах файлов и именах каталогов". ответ, предоставленный sixlettervaliables, вдается в большее количество подробностей.

97
ответ дан Community 23 November 2019 в 21:48
поделиться

Имена файлов Windows довольно нестроги, поэтому действительно это даже не могло бы быть что большая часть проблемы. Символы, которые запрещены Windows:

\ / : * ? " < > |

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

-1
ответ дан Justin Poliey 23 November 2019 в 21:48
поделиться

Регулярные выражения являются излишеством для этой ситуации. Можно использовать String.IndexOfAny() метод в сочетании с Path.GetInvalidPathChars() и Path.GetInvalidFileNameChars().

Также примечание, что и Path.GetInvalidXXX() методы клонируют внутренний массив и возвращают клон. Таким образом, если Вы собираетесь быть выполнением этого много (тысячи и тысячи времен), можно кэшировать копию недопустимого массива символов для повторного использования.

2
ответ дан nhahtdh 23 November 2019 в 21:48
поделиться

От MSDN, вот список символов, которые не позволяются:

<блок цитирования> <блок цитирования>

Использование почти любой символ в текущей кодовой странице для имени, включая символы Unicode и символы в расширенном наборе символов (128†“255), за исключением следующего:

  • следующие зарезервированные символы не позволяются: <>": / \|? *
  • Символы, целочисленные представления которых находятся в диапазоне от нуля до 31, не позволяются.
  • Любой другой символ, который не позволяет система конечного файла.
3
ответ дан Mark Biek 23 November 2019 в 21:48
поделиться

Также ДОВОД "ПРОТИВ", PRN, AUX, NUL, COM# и немногие другие никогда не являются легальными именами файлов ни в каком каталоге ни с каким расширением.

5
ответ дан 23 November 2019 в 21:48
поделиться

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

7
ответ дан David Clarke 23 November 2019 в 21:48
поделиться

Microsoft Windows: ядро Windows запрещает использование символов в диапазоне 1-31 (т.е. 0x01-0x1F) и символов "*: <>? \|. Хотя NTFS позволяет каждому компоненту контура (каталог или имя файла) быть 255 символами долго и путями приблизительно до 32 767 символов в длину, ядро Windows только поддерживает пути до 259 символов в длину. Кроме того, Windows запрещает использование имен устройств MS-DOS AUX, CLOCK$, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, ДОВОД "ПРОТИВ", LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, NUL и PRN, а также эти имена с любым расширением (например, AUX.txt), кроме тех случаев, когда с помощью Долгих путей UNC (напр. \.\C:\nul.txt или \? \D:\aux\con). (На самом деле CLOCK$ может использоваться, если расширение обеспечивается.) Эти ограничения только относятся к Windows - Linux, например, позволяет использование" *: <>? \| даже в NTFS.

Источник: http://en.wikipedia.org/wiki/Filename

8
ответ дан Martin Faartoft 23 November 2019 в 21:48
поделиться

Один угловой случай для учета, который удивил меня, когда я сначала узнал об этом: Windows позволяет вести пробелы в именах файлов! Например, следующее все легальные, и отличные, имена файлов в Windows (минус кавычки):

"file.txt"
" file.txt"
"  file.txt"

Одна еда на дом от этого: Соблюдите осторожность при записи кода, который обрезает пробел продвижения/запаздывания от строки имени файла.

18
ответ дан Jon Schneider 23 November 2019 в 21:48
поделиться

Это - то, что я использую:

    public static bool IsValidFileName(this string expression, bool platformIndependent)
    {
        string sPattern = @"^(?!^(PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d|\..*)(\..+)?$)[^\x00-\x1f\\?*:\"";|/]+$";
        if (platformIndependent)
        {
           sPattern = @"^(([a-zA-Z]:|\\)\\)?(((\.)|(\.\.)|([^\\/:\*\?""\|<>\. ](([^\\/:\*\?""\|<>\. ])|([^\\/:\*\?""\|<>]*[^\\/:\*\?""\|<>\. ]))?))\\)*[^\\/:\*\?""\|<>\. ](([^\\/:\*\?""\|<>\. ])|([^\\/:\*\?""\|<>]*[^\\/:\*\?""\|<>\. ]))?$";
        }
        return (Regex.IsMatch(expression, sPattern, RegexOptions.CultureInvariant));
    }

первый шаблон создает регулярное выражение, содержащее недопустимые/недопустимые имена файлов и символы для платформ Windows только. Второй делает то же, но гарантирует, что имя законно для любой платформы.

22
ответ дан Spook 23 November 2019 в 21:48
поделиться

Попытайтесь использовать его, и прерывание для ошибки. Позволенный набор может измениться через файловые системы, или через различные версии Windows. Другими словами, если Вы хотите, знают, нравится ли Windows имя, вручите ему имя и позвольте ему сказать Вам.

25
ответ дан 23 November 2019 в 21:48
поделиться

Для [1 113].Net Платформы до 3,5 это должно работать:

Регулярное выражение, соответствующее, должно получить Вас часть пути. Вот отрывок с помощью System.IO.Path.InvalidPathChars постоянный;

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

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

    return true;
}

Для [1 114].Net Платформы после 3.0 это должно работать:

http://msdn.microsoft.com/en-us/library/system.io.path.getinvalidpathchars (v=vs.90) регулярное выражение .aspx

, соответствующее, должен получить Вас часть пути. Вот отрывок с помощью System.IO.Path.GetInvalidPathChars() постоянный;

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

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

    return true;
}

, Как только Вы знаете, что, необходимо также проверить на различные форматы, например, c:\my\drive и \\server\share\dir\file.ext

63
ответ дан David Clarke 23 November 2019 в 21:48
поделиться

От [1 111] "Именование MSDN Файла или каталога", вот общие соглашения для того, что легальное имя файла находится под Windows:

можно использовать любой символ в текущей кодовой странице (Unicode/ANSI выше 127), кроме:

  • < > : " / \ | ? *
  • Символы, целочисленные представления которых 0-31 (меньше, чем пространство ASCII)
  • Любой другой символ, который не позволяет система конечного файла (говорят, запаздывающие периоды или пробелы)
  • Любое из названий DOS: ДОВОД "ПРОТИВ", PRN, AUX, NUL, COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9 (и избегают AUX.txt, и т.д.)
  • имя файла являются всеми периодами

Некоторые дополнительные вещи проверить:

  • Пути к файлам (включая имя файла) не могут иметь больше чем 260 символов (которые не используют \?\, префикс)
  • пути к файлам Unicode (включая имя файла) больше чем с 32 000 символов при использовании \?\ (отмечают, что префикс может развернуть компоненты каталога и заставить его переполнять этих 32 000 пределов)
120
ответ дан rory.ap 23 November 2019 в 21:48
поделиться

Вопрос, Вы пытающийся определить, является ли путь легальным путем окон, или если законно в системе, куда код работает. ? Я думаю, что последний более важен, так лично, я, вероятно, анализировал бы полный путь и попытку использовать _mkdir для создания каталога, которого принадлежит файл, затем попытайтесь создать файл.

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

6
ответ дан kfh 23 November 2019 в 21:48
поделиться

Этот класс очищает имена файлов и пути; используйте его как

var myCleanPath = PathSanitizer.SanitizeFilename(myBadPath, ' ');

Вот код:

/// <summary>
/// Cleans paths of invalid characters.
/// </summary>
public static class PathSanitizer
{
    /// <summary>
    /// The set of invalid filename characters, kept sorted for fast binary search
    /// </summary>
    private readonly static char[] invalidFilenameChars;
    /// <summary>
    /// The set of invalid path characters, kept sorted for fast binary search
    /// </summary>
    private readonly static char[] invalidPathChars;

    static PathSanitizer()
    {
        // set up the two arrays -- sorted once for speed.
        invalidFilenameChars = System.IO.Path.GetInvalidFileNameChars();
        invalidPathChars = System.IO.Path.GetInvalidPathChars();
        Array.Sort(invalidFilenameChars);
        Array.Sort(invalidPathChars);

    }

    /// <summary>
    /// Cleans a filename of invalid characters
    /// </summary>
    /// <param name="input">the string to clean</param>
    /// <param name="errorChar">the character which replaces bad characters</param>
    /// <returns></returns>
    public static string SanitizeFilename(string input, char errorChar)
    {
        return Sanitize(input, invalidFilenameChars, errorChar);
    }

    /// <summary>
    /// Cleans a path of invalid characters
    /// </summary>
    /// <param name="input">the string to clean</param>
    /// <param name="errorChar">the character which replaces bad characters</param>
    /// <returns></returns>
    public static string SanitizePath(string input, char errorChar)
    {
        return Sanitize(input, invalidPathChars, errorChar);
    }

    /// <summary>
    /// Cleans a string of invalid characters.
    /// </summary>
    /// <param name="input"></param>
    /// <param name="invalidChars"></param>
    /// <param name="errorChar"></param>
    /// <returns></returns>
    private static string Sanitize(string input, char[] invalidChars, char errorChar)
    {
        // null always sanitizes to null
        if (input == null) { return null; }
        StringBuilder result = new StringBuilder();
        foreach (var characterToTest in input)
        {
            // we binary search for the character in the invalid set. This should be lightning fast.
            if (Array.BinarySearch(invalidChars, characterToTest) >= 0)
            {
                // we found the character in the array of 
                result.Append(errorChar);
            }
            else
            {
                // the character was not found in invalid, so it is valid.
                result.Append(characterToTest);
            }
        }

        // we're done.
        return result.ToString();
    }

}
23
ответ дан 23 November 2019 в 21:48
поделиться

Также важна файловая система назначения.

В NTFS некоторые файлы не могут быть созданы в определенных каталогах. Например, $Boot в root

2
ответ дан 23 November 2019 в 21:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: