Làm cách nào để kiểm tra loại tệp không có phần mở rộng trong python?


87

Tôi có một thư mục chứa đầy các tệp và chúng không có phần mở rộng. Làm cách nào để kiểm tra các loại tệp? Tôi muốn kiểm tra loại tệp và thay đổi tên tệp cho phù hợp. Giả sử một hàm filetype(x)trả về một loại tệp như png. Tôi muốn làm điều này:

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

Làm thế nào để tôi làm điều này?



Bạn sẽ phải cụ thể hơn liên quan đến file types. Ý bạn là xác định xem đó là gif, png, bmp hay jpg? Bạn chỉ muốn biết đó có phải là văn bản / nhị phân không? Thực thi được?
JoeFish

@ thg435, khi bạn có kiểu MIME, có cách nào để chuyển đổi kiểu đó sang phần mở rộng tên tệp phù hợp không?
Mark Ransom

@Mark: vâng, sử dụng đoán_extension , nhưng trên thực tế, mimetypes sẽ không hoạt động ở đây, vì nó dựa trên phần mở rộng tệp. Thứ họ cần là libmagic (xem câu trả lời thứ 2 trên liên kết).
georg

Câu trả lời:


90

Có những thư viện Python có thể nhận dạng tệp dựa trên nội dung của chúng (thường là tiêu đề / số ma thuật) và không dựa vào tên tệp hoặc phần mở rộng.

Nếu bạn đang giải quyết nhiều loại tệp khác nhau, bạn có thể sử dụng python-magic. Đó chỉ là một liên kết Python cho magicthư viện được thiết lập tốt . Điều này có một danh tiếng tốt và (sự chứng thực nhỏ) trong việc sử dụng hạn chế mà tôi đã thực hiện, nó đã rất vững chắc.

Ngoài ra còn có các thư viện cho các loại tệp chuyên biệt hơn. Ví dụ: thư viện chuẩn Python có imghdrmô-đun làm điều tương tự chỉ đối với các loại tệp hình ảnh.

Nếu bạn cần kiểm tra loại tệp không phụ thuộc (Python thuần túy), hãy xem filetype.


2
Gói python-magic-win64làm việc cho tôi trong Windows
ChesuCR

2
imghdr với sự kết hợp của filetype làm việc cho tôi trong cửa sổ
Hrushikesh Dhumal

61

Các Python ma thuật thư viện cung cấp các chức năng mà bạn cần.

Bạn có thể cài đặt thư viện với pip install python-magicvà sử dụng nó như sau:

>>> 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'

Mã Python trong trường hợp này đang gọi đến libmagic bên dưới mui xe, là cùng một thư viện được sử dụng bởi lệnh * NIX file. Do đó, điều này thực hiện tương tự như các câu trả lời dựa trên quy trình con / trình bao, nhưng không có chi phí đó.


6
Hãy lưu ý rằng gói debian / ubuntu được gọi là python-magic khác với gói pip cùng tên. Cả hai đều import magiccó nội dung không tương thích. Xem stackoverflow.com/a/16203777/3189 để biết thêm.
Hamish Downer

1
@Richard Bạn có phiền khi giải thích thêm về khía cạnh trên không? Điều gì làm cho python-magicthư viện hiệu quả hơn khi sử dụng các phương pháp tiếp cận quy trình con?
Greg

9

Trên unix và linux có filelệnh đoán loại tệp. Thậm chí có một cổng cửa sổ .

Từ trang người đàn ông :

Tệp kiểm tra từng đối số để cố gắng phân loại đối số. Có ba bộ bài kiểm tra, được thực hiện theo thứ tự này: bài kiểm tra hệ thống tệp, bài kiểm tra số ma thuật và bài kiểm tra ngôn ngữ. Thử nghiệm đầu tiên thành công sẽ làm cho loại tệp được in.

Bạn sẽ cần chạy filelệnh với subprocessmô-đun và sau đó phân tích cú pháp kết quả để tìm ra phần mở rộng.

chỉnh sửa: Bỏ qua câu trả lời của tôi. Hãy sử dụng câu trả lời của Chris Johnson để thay thế.


+1 Tôi không nhận ra fileđã làm nhiều như vậy. # file arc.gif arc.gif: GIF image data, version 89a, 234 x 269
JoeFish

Chà, tôi đã hy vọng ai đó có câu trả lời tốt hơn. OP vẫn còn rất nhiều việc, nó không phải là một lệnh gọi hàm đơn giản.
Steven Rumbalski

2
+1 Một lợi ích khi sử dụng filelệnh là nó có nguồn gốc trên (hầu hết?) Các bản phân phối Linux trong khi lệnh python-magickhông có và phải được tải xuống và cài đặt trước khi có thể sử dụng. Đây là một phần của vấn đề nếu tập lệnh sử dụng mô-đun được cho là có thể di động.
HelloGoodbye

7

Trong trường hợp hình ảnh, bạn có thể sử dụng imghdrmô-đun.

>>> import imghdr
>>> imghdr.what('8e5d7e9d873e2a9db0e31f9dfc11cf47')  # You can pass a file name or a file object as first param. See doc for optional 2nd param.
'png'

Python 2 imghdr doc
Python 3 imghdr doc


6

Bạn cũng có thể cài đặt fileràng buộc chính thức cho Python, một thư viện được gọi là file-magic(nó không sử dụng ctypes, chẳng hạn python-magic).

Nó có sẵn trên PyPI dưới dạng ma thuật tệp và trên Debian dưới dạng ma thuật trăn . Đối với tôi thư viện này là tốt nhất để sử dụng vì nó có sẵn trên PyPI và Debian (và có thể là các bản phân phối khác), giúp quá trình triển khai phần mềm của bạn dễ dàng hơn. Tôi cũng đã viết blog về cách sử dụng nó .


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

Như Steven đã chỉ ra, đó subprocesslà con đường. Bạn có thể lấy đầu ra lệnh bằng cách trên như bài viết này đã nói


Và làm thế nào để bạn nắm bắt đầu ra?
Mark Ransom

@MarkRansom xin lỗi mà không phải là một cách tốt, vui lòng xem cập nhật của tôi ở trên
xvatar

Nếu bạn cần tương tác với hệ thống của mình thay vì sử dụng thư viện Python, thì giải pháp này thường là không tối ưu vì nó có thể không hữu ích trong các hệ điều hành khác có API khác.
erikbwork 17/12/13

4

Với thư viện quy trình con mới hơn, bây giờ bạn có thể sử dụng mã sau (* giải pháp chỉ 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

Cảm ơn vì câu trả lời. BTW, bạn không nên sử dụng str.split () trên dòng cmd. sử dụng shlex.split (cmd).
emnoor

Thay vì sử dụng shlex.split, tại sao không chỉ chạy subprocess.check_output(['file', '--mime-type', filename])?
Flimm

1

Ngoài ra, bạn có thể sử dụng mã này (python thuần túy bởi 3 byte tệp tiêu đề):

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"

mà không cần cài đặt gói nào [và phiên bản cập nhật]


Làm cách nào để kiểm tra xlsx?
Harsha Biyani

Bạn có thể sử dụng 4 hoặc 8 byte. XLSX (Tài liệu định dạng MS Office Open XML) => 50 4B 03 04 (4 byte) => ASCII (PK ••) hoặc XLSX (tài liệu MS Office 2007) => 50 4B 03 04 14 00 06 00 (8 byte) = > ASCII (PK ••••••)
thường xanh

0

Chỉ hoạt động cho Linux nhưng Sử dụng mô-đun python "sh", bạn có thể chỉ cần gọi bất kỳ lệnh shell nào

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

pip cài đặt sh

nhập khẩu sh

sh.file ("/ root / file")

Đầu ra: / root / file: văn bản ASCII

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.