我试图弄清楚文件的文件类型,而不使用外部库或“文件”命令。
我查看了很多帖子和帖子,他们指向使用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
提前谢谢你!
答案 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);
您可能需要查看此内容以获取更多详细信息,
答案 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()对你没有多大用处。