如何在python中检查没有扩展名的文件的类型?


87

我的文件夹充满了文件,没有扩展名。如何检查文件类型?我想检查文件类型并相应地更改文件名。假设函数filetype(x)返回的文件类型为png。我想做这个:

files = os.listdir(".")
for f in files:
    os.rename(f, f+filetype(f))

我该怎么做呢?



关于,您必须更具体file types。您是说要确定它是gif,png,bmp还是jpg吗?您是否只想知道它是文本还是二进制?可执行的?
JoeFish 2012年

@ thg435,一旦有了MIME类型,就可以将其转换为合适的文件扩展名吗?
Mark Ransom

@Mark:是的,请使用guess_extension,但是实际上,mimetypes在这里不起作用,因为它基于文件扩展名。他们需要的是libmagic(请参阅链接上的第二个答案)。
乔治,2012年

1
试试这个pypi.org/project/filetype吗?
zx1986

Answers:


88

有一些Python库可以根据文件的内容(通常是标头/幻数)识别文件,并且不依赖文件名或扩展名。

如果要处理许多不同的文件类型,则可以使用python-magic。那只是完善的magic库的Python绑定。在我的有限使用中,它具有良好的声誉和(很少认可),它是可靠的。

还有一些用于更专业的文件类型的库。例如,Python标准库具有imghdr仅针对图像文件类型执行相同操作的模块。

如果需要无依赖项(纯Python)文件类型检查,请参见filetype


2
该软件包python-magic-win64在Windows中对我
有用-ChesuCR

2
imghdr文件类型的组合在Windows中为我工作
Hrushikesh Dhumal

61

Python的魔术库提供您需要的功能。

您可以pip install python-magic使用来安装该库并按以下方式使用它:

>>> import magic

>>> magic.from_file('iceland.jpg')
'JPEG image data, JFIF standard 1.01'

>>> magic.from_file('iceland.jpg', mime=True)
'image/jpeg'

>>> magic.from_file('greenland.png')
'PNG image data, 600 x 1000, 8-bit colormap, non-interlaced'

>>> magic.from_file('greenland.png', mime=True)
'image/png'

在这种情况下,Python代码正在幕后调用libmagic,这与* NIXfile命令使用的库相同。因此,这与基于子进程/基于shell的答案具有相同的作用,但是没有开销。


6
注意,名为python-magic的debian / ubuntu软件包与同名的pip软件包不同。两者都是import magic但内容不兼容。有关更多信息,请参见stackoverflow.com/a/16203777/3189
Hamish Downer

1
@Richard您介意开销方面的细节吗?是什么使该python-magic库比使用子过程方法更有效率?
格雷格

9

在UNIX和Linux上,有file命令来猜测文件类型。甚至还有一个Windows端口

手册页

文件测试每个参数以尝试对其进行分类。有三组测试,按此顺序执行:文件系统测试,幻数测试和语言测试。第一个成功的测试导致打印文件类型。

您将需要对模块运行file命令,subprocess然后解析结果以找出扩展名。

编辑: 忽略我的答案。改用克里斯·约翰逊的答案


+1我没意识到file那么多。 # file arc.gif arc.gif: GIF image data, version 89a, 234 x 269
JoeFish 2012年

好吧,我希望有人能有一个更好的答案。OP仍然有很多工作要做,这不是简单的函数调用。
Steven Rumbalski 2012年

2
+1使用该file命令的一个好处是,它在(大多数?)Linux发行版中是本机的,而python-magic不是,并且必须先下载并安装才能使用。如果使用该模块的脚本应该是可移植的,那么这是一个问题。
HelloGoodbye 2014年



6
import subprocess
p = sub.Popen('file yourfile.txt', stdout=sub.PIPE, stderr=sub.PIPE)
output, errors = p.communicate()
print(output)

正如史蒂文指出subprocess的那样。你可以得到上面,因为这的方式输出指令


以及如何捕获输出?
Mark Ransom 2012年

@MarkRansom对不起,这不是一个好方法,请参阅上面的更新
xvatar 2012年

如果您需要与系统进行交互而不是使用Python库,则该解决方案在大多数情况下都是次优的,因为该解决方案在具有不同API的其他操作系统中可能没有用。
erikbwork 2013年

4

使用更新的子流程库,您现在可以使用以下代码(*仅nix解决方案):

import subprocess
import shlex

filename = 'your_file'
cmd = shlex.split('file --mime-type {0}'.format(filename))
result = subprocess.check_output(cmd)
mime_type = result.split()[-1]
print mime_type

谢谢你的回答。顺便说一句,您不应在cmd行上使用str.split()。使用shlex.split(cmd)insteed。
emnoor 2014年

shlex.split为什么不运行而不是使用subprocess.check_output(['file', '--mime-type', filename])
Flimm

1

您也可以使用以下代码(头文件的3个字节的纯python):

full_path = os.path.join(MEDIA_ROOT, pathfile)

try:
    image_data = open(full_path, "rb").read()
except IOError:
    return "Incorrect Request :( !!!"

header_byte = image_data[0:3].encode("hex").lower()

if header_byte == '474946':
    return "image/gif"
elif header_byte == '89504e':
    return "image/png"
elif header_byte == 'ffd8ff':
    return "image/jpeg"
else:
    return "binary file"

没有安装任何软件包[和更新版本]


如何检查xlsx?
Harsha Biyani

您可以使用4或8个字节。XLSX(MS Office Open XML格式文档)=> 50 4B 03 04(4字节)=> ASCII(PK••)XLSX(MS Office 2007文档)=> 50 4B 03 04 14 00 06 00(8字节)= > ASCII(PK••••••)
常绿的

0

仅适用于Linux,但是使用“ sh” python模块,您可以简单地调用任何shell命令

https://pypi.org/project/sh/

点安装sh

进口sh

sh.file(“ / root / file”)

输出:/ root / file:ASCII文本

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.