如何在C ++中找到基础文件类型?

时间:2014-07-15 05:23:22

标签: c++ linux windows

在* nix系统中有一个名为'file'的命令,它可以告诉你文件的基础类型。比如,如果将二进制可执行文件的名称重命名为foo.txt,或者将mp3文件重命名为.txt,系统将始终告诉您文件的真实类型。但是在Windows中,似乎没有这样的功能,如果将可执行文件重命名为.txt,则无法执行它。任何人都可以向我解释这是如何在* nix系统中完成的,如何使用C ++找到文件的真实类型,特别是在windows中,我不能使用std :: system(“file blah”)?

4 个答案:

答案 0 :(得分:2)

文件实用程序使用libmagic库。它识别文件类型解析"特殊"文件中的字段 当然,您可以自己编程识别某些格式,但有时这需要大量的工作。例如。当你试图区分不同格式的MP4时。

该图书馆的开发人员做了大量的工作。因此,如果你希望得到上帝的结果来说明你处理的是什么类型的格式,那么它建议使用他们的结果。(这是一个很大的领域,真的,如果你知道你正在使用什么类型的格式,更好地依赖然后他们在你的代码上)

文件工具 - http://www.darwinsys.com/file/
您可以下载源代码并查看他们使用的真正多种不同的识别类型。 下载档案文件-4.26 - >魔术 - > Magdir

我个人幸运地在Windows ftp://ftp.astron.com/pub/file/

上编译文件4.26

警告
这只是一种约定,某些格式的文件应该具有预定义的签名,并且它几乎总是如此,并且有助于正确识别文件格式。 如果它不是关注点,你肯定可以信任签名。但请记住,任何有足够知识和愿望的人都可以在十六进制编辑器中打开文件并使用位进行另一种格式的文件。

答案 1 :(得分:0)

UNIX 文件 命令使用启发式扫描。有一个幻数数据库,通常在 / usr / share / file / magic / etc / magic / ,允许您添加新文件"类型& #34;由file命令识别。它只是探测文件以在其内容中查找幻数(签名)。

UNIX传统上没有与Windows相同类型的文件扩展名和类型关联,尽管最近Linux正在积累这种关联。

我认为在Windows上你至少要检查文件扩展名关联是否正确。但即使在给定的扩展(例如.txt)内,单个程序也可以执行其自己的启发式算法。例如,记事本在打开文件时必须对字符编码进行有根据的猜测。 Raymond Chen在他的博客中写了一篇关于它的好读物The Old New Thing - The Notepad file encoding problem, redux

答案 2 :(得分:0)

命令reference建议将类型信息保存到外部位置以供进一步使用。它还提到了魔术数字,它引用了file signatures

对文件类型100%肯定是理论上不可能的,因为没有关于某个类型应该包含什么的精确规则。即使它们是这样的规则,也可以改变文件以使其看起来像另一个。虽然签名和扩展都可以让您很好地了解类型实际是什么,但您仍然需要面对处理错误类型的可能性。

答案 3 :(得分:0)

即使在Unix / Linux中,系统也无法真正知道文件的类型。 "文件"程序通过将文件的内容与表征各种常见文件类型的模式数据库进行比较来进行有根据的猜测,但它不过是一个猜测 - 它并不知道所有可能的文件格式,它确实知道它们可能是错误的。

完全可以编写类似" file"的程序。对于Windows;它并不依赖于操作系统中的任何特殊功能。 Cygwin提供了"文件的Windows端口"程序,例如。

将程序重命名为.txt扩展名的问题与"文件"无关。程序。这是因为Windows决定文件是否基于其名称(特别是其扩展名)可执行,而Unix / Linux根据其权限决定文件是否可执行 - 其内容。如果您在Linux系统上chmod a-x程序,系统会认为它是不可执行的,就像从Windows上的程序中删除.exe扩展名一样。