【问题标题】:How to determine file type?如何确定文件类型?
【发布时间】:2011-05-09 20:10:10
【问题描述】:

我需要知道我的文件是否为音频文件:mp3、wav 等...
如何做到这一点?

【问题讨论】:

  • 除了扩展名之外,什么决定了您的文件类型?并非每个文件都有指定其类型的元数据。
  • 确定文件类型的文件头。音频文件、视频文件、djvu文件等……
  • 简单的答案就是将文件作为字节流打开,然后读取前 20 个左右的字节。但是你应该小心,因为对于签名字节如何存储在文件头中没有真正的标准。您要么必须测试所有常见案例,要么提供一些出色的文档。

标签: c# file audio mp3


【解决方案1】:

嗯,最可靠的方法是为您想要检测的文件类型编写一个解析器,然后尝试——如果没有错误,显然是您尝试的类型。然而,这是一种昂贵的方法,但它可以确保您也可以成功加载文件,因为它还会检查文件的其余部分是否符合语义。

一个更便宜的变体是寻找“魔术”字节——文件开头的签名或已知的偏移量。例如,如果一个文件以 ID3 标签开头,您可以合理地确定它是一个 MP3 文件。如果一个文件以RIFF¼↕☻ WAVEfmt 开头,那么它就是一个WAV 文件。然而,这样的检测并不能保证你的文件确实属于那种类型——它可能只是签名并跟随那个垃圾。

【讨论】:

  • 如果他使用的 lib/codec 可以播放所有这些文件格式会怎样?
【解决方案2】:

您可以使用文件扩展名来弄清楚:

using System.IO;

class Program
{
    static void Main()
    {
        string filepath = @"C:\Users\Sam\Documents\Test.txt";

        string extension = Path.GetExtension(filepath);
        if (extension  == ".mp3")
        {
            Console.WriteLine(extension);
        }
    }
}

文件扩展名是操作系统确定它正在处理的文件类型的第一个调用点,如果你真的想 100% 知道文件类型,唯一的方法就是读入文件。但这有一个问题,图像文件很容易,因为它们包含的标题格式很容易阅读,但是如果文件类型完全可变,它可能会变得更复杂。

您可以查看旧帖子上的 this 帖子以获得一些帮助。 Here 是关于仅查找媒体文件类型的帖子。

最终这取决于你为什么要这样做。

【讨论】:

  • 我可以随意更改扩展名,但我需要知道文件类型。
【解决方案3】:

虽然您可以使用扩展名来合理猜测文件是什么,但不能保证 100% 的时间都能正常工作。如果您的目标是 Windows,那么它在 99.9% 的时间里工作,因为这就是 Windows 跟踪什么文件是什么类型的方式。

如果您从非 Windows 源获取文件,唯一可靠的方法是打开文件并查找可以明确识别它的特定字符串或字节集。例如,您可以在 mp3 文件中查找 ID3 tags

ID3v1标签占用128字节,以字符串TAG开头。

ID3v2 标签的大小可变,通常出现在文件的开头,以辅助流媒体。

您能走多远取决于您希望解决方案有多健壮,并且确实取决于始终存在的标头或模式。

这样做可以帮助防范恶意内容,其中有人将恶意软件作为 mp3 文件发布(例如),并希望它仅由容易受到某种利用的程序运行(可能是缓冲区溢出)。

【讨论】:

  • +1 指出文件扩展名是 Windows 确定文件类型(以及应在哪个应用程序中打开)的方式。如果此方法中断,则文件很可能对用户来说已经“损坏”,因为他们无法在 Windows 资源管理器中打开它。 Mac OS X 过去以不同的方式处理这个问题,但从 10.6 开始,他们转向黑暗面,将文件扩展名作为用于将文件与其创建者关联的主要元数据。
  • @Cody - 关于 Mac 的有趣点,我认为他们使用了“unix”方法。
  • 实际上,要保持与 pre-OS X 中使用的在资源分支中嵌入类型代码和创建者代码的分叉方法的向后兼容性要复杂得多。在 10.4 中,Apple 开始使用统一类型标识符,这是我们在 Windows 世界中梦寐以求的东西。然而,在 10.6 之前,如果文件存在,仍会根据其创建者代码打开文件,但此后此行为已被删除,所有文档(即使是具有旧版创建者代码的文档)都仅使用文件扩展名。
【解决方案4】:

this 帖子。您最终将文件中的前(最多)256 个字节的数据传递给 FindMimeFromData(Urlmon.dll 的一部分)。

【讨论】:

    【解决方案5】:
    Path.GetExtension(PathToFile)
    

    【讨论】:

    • 不,它返回文件扩展名。但我需要知道文件类型
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 2012-11-05
    • 2012-07-04
    • 2013-04-21
    • 1970-01-01
    相关资源
    最近更新 更多