У вас есть еще одна опция, которая является Протокол сопоставления NAT-портов (NAT-PMP) NAT-PMP широко используется приложениями VoIP, такими как клиенты Skype или BitTorrent P2P.
Попробуйте что-то вроде этого:
string fileName = "something";
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
{
fileName = fileName.Replace(c, '_');
}
Редактирование:
С тех пор GetInvalidFileNameChars()
возвратит 10 или 15 символов, лучше использовать StringBuilder
вместо простой строки; исходная версия займет больше времени и использует больше памяти.
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.
Мне была нужна система, которая не могла создать коллизии, таким образом, я не мог отобразить несколько символов на один. Я закончил с:
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)));
}
}
У Диего действительно есть правильное решение, но есть одна очень маленькая ошибка. Используемая версия string.Replace должна быть string.Replace (char, char), строки нет .Replace (char, string)
Я не могу редактировать ответ, иначе я бы просто сделал второстепенный изменить.
Так должно быть:
string fileName = "something";
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
{
fileName = fileName.Replace(c, '_');
}