在C中确定文件的文件类型

时间:2015-11-16 22:19:20

标签: c unix file-type

我试图弄清楚文件的文件类型,而不使用外部库或“文件”命令。

我查看了很多帖子和帖子,他们指向使用stat()函数(unix man stat)并使用stat结构中的“st_mode”。

但我不知道该怎么做,也无法找到一个好的例子。

例如程序接收文件F,我希望能够读取类似于下面程序的F并给出类似的输出。并且F的文件类型是PDF,但它没有扩展名。

更多示例:如果我有foo.pdf,但我将扩展名更改为* .png(foo.png)我可以通过我的程序“foo.png”并说它实际上是.pdf文件。

创建文件时,它会生成一个“幻数”,例如PDF格式,PDF文件的幻数以“%PDF”开头(十六进制25 50 44 46)。“

如何使用幻数来计算文件类型。

我知道需要在我的结尾处制作一些类型的表来支持文件。我只做了一小撮< 10。

A
E
B
J
C
M
D
Z
F
L
G
Y
H
X
I
V
K
W
N
R
O
Q
P
U
S
T

提前谢谢你!

3 个答案:

答案 0 :(得分:2)

像Jonathon Reinhart指出的那样,不要试图重新使用轮子#include <stdio.h> #include <magic.h> int main(void) { struct magic_set *magic = magic_open(MAGIC_MIME|MAGIC_CHECK); magic_load(magic,NULL); printf("Output1: '%s'\n",magic_file(magic,"ValgrindOut.xml")); printf("Output2: '%s'\n",magic_file(magic,"program")); printf("Output3: '%s'\n",magic_file(magic,"Chapter9.pdf")); printf("Output4: '%s'\n",magic_file(magic,"test.txt")); printf("Output5: '%s'\n",magic_file(magic,"linux-3.17.tar.xz")); printf("Output6: '%s'\n",magic_file(magic,"gcc-5.2.0.tar.gz")); printf("Output7: '%s'\n",magic_file(magic,"/home/michi")); return 0; }

gcc -o program program.c -lmagic

编译:

Output1: 'application/xml; charset=us-ascii'
Output2: 'application/x-executable; charset=binary'
Output3: 'application/pdf; charset=binary'
Output4: 'text/plain; charset=utf-8'
Output5: 'application/x-xz; charset=binary'
Output6: 'application/gzip; charset=binary'
Output7: 'inode/directory; charset=binary'

输出:

{{1}}

答案 1 :(得分:-1)

大多数文件通常会有一个名为Header / MetaData的部分。它位于文件的此部分/部分中,其中包含有关其自身文件的详细信息。此外,这些Headers/MetaData细分还将包含Signature以标识文件类型。但请注意,这些Signatures中的大多数都位于Hex Signature format

示例

PDF签名 - 25 50 44 46(十六进制)或%PDF JPEG签名 - 启动FF D8和文件结尾FF D9

所以,基本上你需要以二进制格式打开文件并解析文件结构并进行比较,看它是否与你在程序中定义的任何一种文件类型相匹配。就像你想要检查它是否&# 39; s pdf文件然后您需要首先以二进制模式打开文件,然后扫描文件,直到您获得与bytcode/hex code文件的bytcode/hex code匹配的pdf。在二进制模式下使用C fopen()函数,即"rb"

或者您可以正常打开文件而不使用二进制模式,

unsigned int data;
data=fgetc(pfile);

您可能需要查看此内容以获取更多详细信息,

  1. Magic Number
  2. File Signatures

答案 2 :(得分:-3)

首先,您需要包含sys / stat.h

接下来,您需要在代码中声明struct stat:

struct stat s

接下来,将指针传递给stat结构以及文件/对象名称:

returnval = stat("filename", &s);

检查返回值,你得到&lt; 0错误。如果对象/文件不存在错误,我们可以使用宏函数来确定文件类型:

if (S_ISREG(s.st_mode))
    /* Regular text file... */
else if (S_ISDIR(s.st_mode))
    /* Is a directory.... */

我建议您查看手册页(man 3 stat),它将为您提供st_type可能存在的所有类型(它可用于标识文件,目录,块设备,sym链接等) )

stat结构的另一个非常有用的成员是st_size,它为您提供以字节为单位的文件大小。

ETA - stat()系统调用不会告诉您文件是PDF还是类似的东西 - 通常我们会使用扩展程序,如果没有扩展程序并且您是尝试识别特定的文件格式,然后stat()对你没有多大用处。