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

14
在Windows 7中,我可以为文件添加元数据,例如标题、评分等等。这些元数据会存储在哪里呢?对于NTFS文件系统,它们可能使用备用数据流来存储这些元数据,但是如果我使用的是FAT32文件系统,它们是如何实现的呢?是否有API可以利用这个功能呢?

这可能与这个有关吗? - default
不,正如我所说的,由于它也适用于FAT,因此不能涉及任何备用数据流,因为FAT不支持它们。 - codymanix
1
在FAT和NTFS文件系统上,它们都可以使用扩展属性(http://en.wikipedia.org/wiki/Extended_file_attributes)。 - Larry Osterman
4个回答

5
在Windows 7中,我可以使用资源管理器为文件添加元数据,例如标题、评级等。这些元数据被称为“属性”,自Windows Vista以来就已经以这种方式提供。Windows资源管理器以统一的方式呈现属性,这可能会让你误以为它们都来自同一个地方。但事实并非如此。属性通过API向程序员公开。它们存储的位置取决于文件类型和属性类型。例如,文件系统时间戳作为属性公开。媒体文件元数据(例如图像的EXIF或MP3的ID3标签)存储在文件本身中。仍有其他元数据可能存储在附带到您正在检查属性的文件的XML文件中。所以它究竟存储在哪里?答案是:这真的取决于具体实现,您不必担心,也不应该担心。因为正如我所说,这是一个实现细节,从编程的角度来看,担心实现细节意味着绕过API。

您无需担心在API级别处理属性时,属性存储在何处。请参见IShellItem2IPropertyStore COM接口作为入口。

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

我发现最有用的文档是Ben Karas'博客文章系列,始于2006年8月Vista发布之际。他对属性系统进行了全面介绍。这是一个非常有用的教程,对于我使用的Windows 7,它已经100%可行。

不要按照本页面上另一个回答中提供的建议阅读关于COM结构化存储的内容。这仅适用于特定的文件类型。根据Ben Karas的话
注意:许多人错误地调用StgOpenStorageEx。不要这样做!StgOpenStorageEx仅支持特定格式,如OLE复合文档或NTFS次要流存储。StgOpenStorageEx不知道如何从.JPG图像中读取EXIF头。

1
-1 对于“这真的取决于情况,你不必担心,也不应该担心。”理解底层发生的事情有助于调试,当别人做了一些非常愚蠢的事情,然后把它放在你的桌子上时。 - Jason_L_Bens
3
如果我想知道如果我转移到Linux,我的标签是否可用怎么办?我应该花时间通过Windows内置属性系统添加元数据,还是寻找第三方解决方案?如果您考虑维护档案,了解数据存储在哪里非常重要。 - meta-meta

4

从Windows Vista开始,元数据现在存储在文件本身内部。


3
当然,它只适用于某些文件类型。例如,它永远不会适用于文本文件! - David Heffernan

3

1
COM Structured Storage是一个较旧的API。资源管理器中呈现的属性(标题、评级->媒体文件)可以通过IShellItem2IPropertyStore访问。这与COM Structured Storage不同。 - Lumi

1

如果您问的是 .Net 相关问题,您可以使用来自 nuget 的 Microsoft.WindowsAPICodePack-Shell 库访问文件属性。它为Windows 属性提供了一个 .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;
         }
   }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接