Безопасный/Позволенный инструмент для очистки имени файла для.NET

Статические методы не , инстанцировал как таковой, они просто доступны без ссылки на объект.

вызов А к статическому методу сделан через имя класса, не через ссылку на объект и код Промежуточного языка (IL) для вызова, это назовет абстрактный метод через название класса, который определил его, не обязательно название класса, который Вы использовали.

Позволяют мне показать пример.

Со следующим кодом:

public class A
{
    public static void Test()
    {
    }
}

public class B : A
{
}

, Если Вы называете B.Test, как это:

class Program
{
    static void Main(string[] args)
    {
        B.Test();
    }
}

Тогда фактический код в Основном методе следующие:

.entrypoint
.maxstack 8
L0000: nop 
L0001: call void ConsoleApplication1.A::Test()
L0006: nop 
L0007: ret 

, Как Вы видите, вызов выполняется к A.Test, потому что это был класс, который определил его, а не к B.Test, даже при том, что можно записать коду тот путь.

, Если Вы имели типы классов , как в Дельфи, где можно сделать переменную, относящуюся к типу и не объекту, у Вас было бы больше использования для виртуального и таким образом абстрактных статических методов (и также конструкторы), но они не доступны, и таким образом статические вызовы являются невиртуальными в.NET.

я понимаю, что разработчики IL могли позволить коду быть скомпилированным, чтобы назвать B.Test и разрешить вызов во времени выполнения, но это все еще не было бы виртуальным, поскольку необходимо будет все еще записать некоторое имя класса там.

Виртуальные методы, и таким образом абстрактные, только полезны при использовании переменной, которая, во времени выполнения, может содержать много различных типов объектов, и Вы таким образом хотите назвать правильный метод для текущего объекта, который Вы имеете в переменной. Со статическими методами необходимо пройти имя класса так или иначе, таким образом, точный метод для вызова известен во время компиляции, потому что он не может и не изменяться.

Таким образом, виртуальные/абстрактные статические методы не доступны в.NET.

6
задан Craig Walker 7 December 2009 в 21:38
поделиться

4 ответа

This problem is not as simple as you may think. Not only are the characters in Path.GetInvalidFileNameChars illegal, there are several filenames, such as "PRN" and "CON", that are reserved by Windows and cannot be created. Any name that ends in "." is also illegal in Windows. Moreover, there are various length limitations. Read the full list here.

If that's not enough, different filesystems have different limitations, for example ISO 9660 filenames cannot start with "-" but can contain it.

9
ответ дан 8 December 2019 в 04:08
поделиться

Не могли бы вы подробнее рассказать, что вы имеете в виду под «генерировать из произвольной строки»? Основываясь на том, что вы говорите, похоже, что вы спрашиваете

Есть ли способ взять произвольную строку и изменить ее таким образом, чтобы она представляла допустимое имя файла?

Если это так, то нет стандартной доступной функции что я знаю. Однако вы можете использовать следующее, которое должно сработать

public static string MakeValidFileName(string name) {
  var invalid = Path.GetInvalidFileNameChars();
  var builder = new StringBuilder();
  foreach ( var cur in name ) {
    builder.Append(invalid.Contains(cur) ? '_' : cur);
  }
  return builder.ToString();
}
2
ответ дан 8 December 2019 в 04:08
поделиться

Вы видели Path.GetInvalidFileNameChars?

Найдено на Действительно полезные классы .NET, часть 1 - System.IO.Path

1
ответ дан 8 December 2019 в 04:08
поделиться

Вы можете использовать Path.GetInvalidFileNameChars , чтобы проверить, какие символы в строке недействительны, и либо преобразовать их в допустимые символы, такие как дефис, либо (если вам нужно двунаправленное преобразование) заменить их с помощью escape-токена, такого как % , с последующим шестнадцатеричным представлением их кодов Unicode (я действительно однажды использовал эту технику, но сейчас не имею кода под рукой).

EDIT : На всякий случай, если кому-то интересно, вот код:

/// <summary>
/// Escapes an object name so that it is a valid filename.
/// </summary>
/// <param name="fileName">Original object name.</param>
/// <returns>Escaped name.</returns>
/// <remarks>
/// All characters that are not valid for a filename, plus "%" and ".", are converted into "%uuuu", where uuuu is the hexadecimal
/// unicode representation of the character.
/// </remarks>
private string EscapeFilename(string fileName)
{
    char[] invalidChars=Path.GetInvalidFileNameChars();

    // Replace "%", then replace all other characters, then replace "."

    fileName=fileName.Replace("%", "%0025");
    foreach(char invalidChar in invalidChars)
    {
        fileName=fileName.Replace(invalidChar.ToString(), string.Format("%{0,4:X}", Convert.ToInt16(invalidChar)).Replace(' ', '0'));
    }
    return fileName.Replace(".", "%002E");
}

/// <summary>
/// Unescapes an escaped file name so that the original object name is obtained.
/// </summary>
/// <param name="escapedName">Escaped object name (see the EscapeFilename method).</param>
/// <returns>Unescaped (original) object name.</returns>
public string UnescapeFilename(string escapedName)
{
    //We need to temporarily replace %0025 with %! to prevent a name
    //originally containing escaped sequences to be unescaped incorrectly
    //(for example: ".%002E" once escaped is "%002E%0025002E".
    //If we don't do this temporary replace, it would be unescaped to "..")

    string unescapedName=escapedName.Replace("%0025", "%!");
    Regex regex=new Regex("%(?<esc>[0-9A-Fa-f]{4})");
    Match m=regex.Match(escapedName);
    while(m.Success)
    {
        foreach(Capture cap in m.Groups["esc"].Captures)
            unescapedName=unescapedName.Replace("%"+cap.Value, Convert.ToChar(int.Parse(cap.Value, NumberStyles.HexNumber)).ToString());
        m=m.NextMatch();
    }
    return unescapedName.Replace("%!", "%");
}
14
ответ дан 8 December 2019 в 04:08
поделиться
Другие вопросы по тегам:

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