Где проводник Windows хранит метаданные файлов?

В Windows 7 я могу добавить метаданные в файлы, например название, рейтинг и т.д. Где эти метаданные хранятся точно? Для NTFS они могут использовать альтернативные потоки данных, но я также вижу, что эти метаданные работают в FAT32, так как они это делают? Существует ли API для использования этой функции?

Ответ 1

Начиная с Windows Vista metadata теперь сохраняется внутри самого файла.

Ответ 2

Windows хранит это в COM структурированное хранилище. Реализация выполняется либо в самом файле (документы Office поддерживают это, либо любой формат файла, поддерживающий структурированное хранилище), либо в самой NTFS.

API доступен здесь: Структурированное хранилище. Интересной функцией является StgOpenStorageEx.

Ниже приведены некоторые сведения о реализации NTFS: Реализация файловой системы IPropertySetStorage-NTFS

Ответ 3

В Windows 7 я могу добавить метаданные в файлы [используя Explorer], например название, рейтинг и т.д. Где эти метаданные хранятся точно?

Эти метаданные называются свойствами. Он был доступен таким образом с Windows Vista.

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

Свойства передаются программисту через API. (См. Ниже.)

Где именно они хранятся, является деталью реализации. Это зависит от типа файла и от свойства. Например, временные метки файловой системы отображаются как свойства. Метаданные медиафайлов, например EXIF ​​для изображений или тегов ID3 ​​для MP3, хранятся в самом файле. Другие метаданные могут храниться в файле XML, сопровождающем файл, свойства которого вы проверяете.

Итак, где он хранится? Ответ: Это действительно зависит, и вам действительно не нужно беспокоиться и не беспокоиться. Поскольку, как я уже сказал, это детализация реализации, и, насколько программирование идет, беспокоиться о деталях реализации означает обход API.

Также вам не нужно беспокоиться о том, где хранятся свойства при работе с ними на уровне API. См. IShellItem2 и IPropertyStore Интерфейсы COM для точка входа.

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

Самая полезная документация, которую я нашел, - это записи блога Бена Караса во время выпуска Vista начиная с августа 2006 года. Он сделал целую серию в системе собственности. Это очень полезный учебник, и для меня, использующего Windows 7, он работал на 100%.

Не следуйте рекомендациям, приведенным в другом ответе на этой странице, чтобы прочитать о COM Structured Storage. Это касается только определенных типов файлов. В словах из слова "Бен Карас" :

Gotcha: Многие люди ошибочно называют StgOpenStorageEx. Не делай этого! StgOpenStorageEx поддерживается только для определенных форматов, таких как OLE Compound Documents или NTFS для вторичного хранилища потоков. StgOpenStorageEx не знает, как читать заголовок EXIF ​​с изображения .JPG.

Ответ 4

Поскольку вы спрашиваете о .Net, вы можете получить доступ к свойствам файла, используя библиотеку Microsoft.WindowsAPICodePack-Shell из nuget. Он предоставляет интерфейс .Net для Свойства Windows.

Пример использования библиотеки выглядит следующим образом:

using System;
using Microsoft.WindowsAPICodePack.Shell.PropertySystem;
using Microsoft.WindowsAPICodePack.Shell;

namespace Properties
{
    public class PictureFileProperties
    {
        public string GetCamera(string filename)
        {
            if (!System.IO.File.Exists(filename))
                return null;

            ShellObject picture = ShellObject.FromParsingName(filename);
            if (picture != null)
            {
                var manufacturer = picture.Properties.GetProperty(SystemProperties.System.Photo.CameraManufacturer)).Value;
                var model = picture.Properties.GetProperty(SystemProperties.System.Photo.CameraModel).Value;
                return string.Format("{0} {1}", manufacturer, model);
            }

            return null;
         }
   }
}