Windows资源管理器在哪里存储文件元数据?

时间:2011-05-21 07:35:39

标签: .net winapi windows-7 metadata explorer

在Windows 7中,我可以将元数据添加到文件中,例如标题,评级等。这个元数据存储在哪里?对于NTFS,他们可能会使用备用数据流,但我这个元数据也恰好在FAT32中工作,那么他们怎么做呢?是否有API可以使用此功能?

4 个答案:

答案 0 :(得分:2)

从Windows Vista开始,metadata现在存储在文件本身内。

答案 1 :(得分:2)

Windows将其存储在COM Structured storage中。实现可以在文件本身(Office文档支持此文件,或支持结构化存储的任何文件格式),也可以在NTFS本身中实现。

此处提供了API:Structured Storage。有趣的功能是StgOpenStorageEx

以下是有关NTFS实施的一些细节:IPropertySetStorage-NTFS File System Implementation

答案 2 :(得分:2)

  

在Windows 7中,我可以使用资源管理器将元数据添加到文件中,例如标题,评级等。这个元数据存储在哪里?

此元数据称为属性。自Windows Vista以来,它已经以这种方式提供。

Windows资源管理器以统一的方式呈现属性,这可能会让您误以为它们都来自同一个商店。但事实并非如此。

属性通过API向程序员公开。 (见下文。)

它们存储的确切位置是实现细节。这取决于文件类型和属性的类型。例如,文件系统时间戳作为属性公开。媒体文件元数据(如图像的EXIF或MP3的ID3标签)存储在文件本身中。还有其他元数据可能存储在XML文件中,该文件伴随着您正在检查其属性的文件。

那么它存储在哪里?答案是:这真的取决于你,你真的不必担心,也不用担心。因为,正如我所说,这是一个实现细节,就编程而言,担心实现细节意味着绕过API。

在API级别处理属性时,您也不必担心存储属性的位置。有关入口点,请参阅IShellItem2IPropertyStore COM接口。

在幕后,Windows Vista及更高版本提供了属性处理程序,它们了解文件类型以及如何读取和写入其属性。您可以编写自己的属性处理程序(使用COM)并将其添加到资源管理器(作为所谓的 shell扩展)。

我发现的最有用的文档是Ben Karas' blog entries around the time of the Vista release starting in August 2006。他在物业系统上完成了一系列的工作。这是一个非常有用的教程,对于我使用Windows 7,它已经100%工作。

请勿按照本页另一个回复中提供的建议阅读 COM结构化存储。这仅适用于特定的文件类型。在words of Ben Karas

  

陷阱:很多人误打电话给StgOpenStorageEx。别这么做!对于特定格式(如OLE复合文档或NTFS辅助流存储),StgOpenStorageEx支持 StgOpenStorageEx不知道如何从.JPG图片中读取EXIF标头。

答案 3 :(得分:0)

由于您询问.Net,您可以使用nuget中的Microsoft.WindowsAPICodePack-Shell库访问文件属性。它为Windows Properties提供.Net接口。

该库的示例用法如下:

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;
         }
   }
}