Кэширование свойств FileInfo в C#

#c# #caching #.net #fileinfo

#c# #кэширование #.net #fileinfo

Вопрос:

Из документации MSDN по FileInfo.Name свойству я вижу, что данные для свойства кэшируются при первом его вызове и будут обновлены только впоследствии с помощью Refresh метода.

У меня есть следующие вопросы, которые я не могу найти или которые не слишком понятны в документации:

  1. Кэшируются ли данные для всех свойств одновременно?

  2. Refresh Метод вызывается при создании FileInfo или только при первом вызове свойства?

  3. Если я вызвал одно свойство, например, Name property, и оно вызвано Refresh , вызовет ли вызов другого свойства, например, DirectoryName property, в первый раз вызов его Refresh снова, или оно вызывается только первым свойством, к которому обращаются во всем классе (см. Вопрос # 1)?

  4. Могу ли я предварительно кэшировать все свойства, вызывая Refresh вручную? (Предполагается, что они не были предварительно кэшированы при создании объекта)

  5. Вызывает ли вызов Refresh вручную свойства, которые предварительно кэшированы, например CreationTime , которые также должны обновляться?

Комментарии:

1. Я бы посоветовал вам загрузить ILSpy wiki.sharpdevelop.net/ILSpy.ashx и изучите реализацию FileInfo. Это лучший способ получить ответы на такие подробные вопросы о внутренней части типов BCL.

2. Я согласен. Также стоит отметить, что теперь (ну, как и в today now) вы можете просматривать справочный источник онлайн. Вот определение FileInfo во всей его красе.

Ответ №1:

  1. На первый взгляд, да. Кажется, что это немного обреченная на провал «оптимизация» для FileInfo извлечения только тех свойств, которые вы извлекали ранее, особенно когда они могут быть (и, вероятно, все они) извлечены в одном вызове API.

  2. Тот факт, что документация вызывает DirectoryInfo методы, которые обслуживают уже кэшированные FileInfo файлы, довольно убедительно указывает (по крайней мере, для меня), что простое построение FileInfo ничего не кэширует. Это имеет смысл — если вы создаете FileInfo напрямую, это может ссылаться на файл, который еще не существует (например, вы планируете его создать), тогда как все методы, которые возвращают кэшированные FileInfo файлы, ссылаются на файлы, которые существуют на момент создания моментального снимка, при условии, что вы собираетесь использовать по крайней мере некоторые из них.

  3. Нет, согласно моему ответу на вопрос 1. Вот почему существует метод обновления.

  4. Я бы предположил это (см. Ответ 1).

  5. ДА. Смотрите ответ 3.

Ответ №2:

Значение свойства CreationTime предварительно кэшируется, если текущий экземпляр объекта FileSystemInfo был возвращен из любого из следующих методов DirectoryInfo:

  • Получить каталоги
  • Получение файлов
  • GetFileSystemInfos
  • Перечисляемые каталоги
  • Перечислять файлы
  • Перечислите файловую систему INFOS

Чтобы получить последнее значение, вызовите метод Refresh.

Если файл, описанный в объекте FileSystemInfo, не существует, это свойство вернет 12:00 полночи 1 января 1601 года нашей эры по всемирному координированному времени (UTC), скорректированное на местное время.

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

(MSDN)

Внутри, Refresh вызывает стандартный Win32API и, таким образом, заполняет все свойства.

 [...]
flag2 = Win32Native.GetFileAttributesEx(path, 0, ref data);
  

Доступ к любому свойству, указанному для обновления, приводит к полному обновлению, например:

 public DateTime LastAccessTimeUtc
{
    [SecuritySafeCritical]
    get
    {
        if (this._dataInitialised == -1)
        {
            this._data = default(Win32Native.WIN32_FILE_ATTRIBUTE_DATA);
            this.Refresh();
        }
        [...]