Как сделать допустимое имя файла Windows из произвольной строки?

У вас есть еще одна опция, которая является Протокол сопоставления NAT-портов (NAT-PMP) NAT-PMP широко используется приложениями VoIP, такими как клиенты Skype или BitTorrent P2P.

85
задан Ken 6 March 2009 в 22:05
поделиться

4 ответа

Попробуйте что-то вроде этого:

string fileName = "something";
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
{
   fileName = fileName.Replace(c, '_');
}

Редактирование:

С тех пор GetInvalidFileNameChars() возвратит 10 или 15 символов, лучше использовать StringBuilder вместо простой строки; исходная версия займет больше времени и использует больше памяти.

143
ответ дан Gabber 5 November 2019 в 15:54
поделиться
fileName = fileName.Replace(":", "-") 

Однако ":" не единственный запрещенный символ для Windows. Необходимо будет также обработать:

/, \, :, *, ?, ", <, > and |

Они содержатся в Системе. IO.Path. GetInvalidFileNameChars ();

Также (в Windows), "." не может быть единственный символ в имени файла (оба ".", "..", "...", и так далее недопустимы). Будьте осторожны при именовании файлов с".", например:

echo "test" > .test.

генерирует файл, названный ".test"

Наконец, если Вы действительно захотите сделать вещи правильно, существуют приблизительно специальные имена файлов , необходимо высматривать. В Windows Вы не можете создать названные файлы:

CON, PRN, AUX, CLOCK$, NUL
COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9
LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.
32
ответ дан Phil Price 5 November 2019 в 15:54
поделиться

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

public static class Extension
{
    /// <summary>
    /// Characters allowed in a file name. Note that curly braces don't show up here
    /// becausee they are used for escaping invalid characters.
    /// </summary>
    private static readonly HashSet<char> CleanFileNameChars = new HashSet<char>
    {
        ' ', '!', '#', ', '%', '&', '\'', '(', ')', '+', ',', '-', '.',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '=', '@',
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
        'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
        '[', ']', '^', '_', '`',
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
        'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    };

    /// <summary>
    /// Creates a clean file name from one that may contain invalid characters in 
    /// a way that will not collide.
    /// </summary>
    /// <param name="dirtyFileName">
    /// The file name that may contain invalid filename characters.
    /// </param>
    /// <returns>
    /// A file name that does not contain invalid filename characters.
    /// </returns>
    /// <remarks>
    /// <para>
    /// Escapes invalid characters by converting their ASCII values to hexadecimal
    /// and wrapping that value in curly braces. Curly braces are escaped by doubling
    /// them, for example '{' => "{{".
    /// </para>
    /// <para>
    /// Note that although NTFS allows unicode characters in file names, this
    /// method does not.
    /// </para>
    /// </remarks>
    public static string CleanFileName(this string dirtyFileName)
    {
        string EscapeHexString(char c) =>
            "{" + (c > 255 ? $"{(uint)c:X4}" : $"{(uint)c:X2}") + "}";

        return string.Join(string.Empty,
                           dirtyFileName.Select(
                               c =>
                                   c == '{' ? "{{" :
                                   c == '}' ? "}}" :
                                   CleanFileNameChars.Contains(c) ? $"{c}" :
                                   EscapeHexString(c)));
    }
}
0
ответ дан 24 November 2019 в 08:11
поделиться

У Диего действительно есть правильное решение, но есть одна очень маленькая ошибка. Используемая версия string.Replace должна быть string.Replace (char, char), строки нет .Replace (char, string)

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

Так должно быть:

string fileName = "something";
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
{
   fileName = fileName.Replace(c, '_');
}
7
ответ дан 24 November 2019 в 08:11
поделиться
Другие вопросы по тегам:

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