python準確判斷檔案型別

pythontab發表於2015-11-08

判斷檔案型別在開發中非常常見的需求,怎樣才能準確的判斷檔案型別呢?首先大家想到的是檔案的字尾,但是非常遺憾的是這種方法是非常不靠譜的,因為檔案的字尾是可以隨意更改的,而大家都知道字尾在linux系統下是沒有這個概念的,所以僅靠判斷字尾無法準確判斷一個檔案的型別。還有第二種方法是判斷檔案的頭,每種檔案在檔案的頭中會標識這種檔案的型別,下面我們來看看如何用python來判斷檔案的型別。

python透過檔案頭判斷檔案型別的方法:

#! /usr/bin/python
# pythontab提醒您注意中文編碼問題,指定編碼為utf-8
# -*- coding: utf-8 -*- 
import struct
# 支援檔案型別 
# 用16進位制字串的目的是可以知道檔案頭是多少位元組 
# 各種檔案頭的長度不一樣,少則2字元,長則8字元 
def typeList(): 
  return { 
    "FFD8FF": "JPEG", 
    "89504E47": "PNG"} 
  
# 位元組碼轉16進位制字串 
def bytes2hex(bytes): 
  num = len(bytes) 
  hexstr = u"" 
  for i in range(num): 
    t = u"%x" % bytes[i] 
    if len(t) % 2: 
      hexstr += u"0"
    hexstr += t 
  return hexstr.upper() 
  
# 獲取檔案型別 
def filetype(filename): 
  binfile = open(filename, 'rb') # 必需二制字讀取 
  tl = typeList() 
  ftype = 'unknown'
  for hcode in tl.keys(): 
    numOfBytes = len(hcode) / 2 # 需要讀多少位元組 
    binfile.seek(0) # 每次讀取都要回到檔案頭,不然會一直往後讀取 
    hbytes = struct.unpack_from("B"*numOfBytes, binfile.read(numOfBytes)) # 一個 "B"表示一個位元組 
    f_hcode = bytes2hex(hbytes) 
    if f_hcode == hcode: 
      ftype = tl[hcode] 
      break
  binfile.close() 
  return ftype 
  
if __name__ == '__main__': 
  print filetype('./test.jpg')

  

常見檔案格式的檔案頭

檔案格式 檔案頭(十六進位制)
JPEG (jpg) FFD8FF
PNG (png) 89504E47
GIF (gif) 47494638
TIFF (tif) 49492A00
Windows Bitmap (bmp) 424D
CAD (dwg) 41433130
Adobe Photoshop (psd) 38425053
Rich Text Format (rtf) 7B5C727466
XML (xml) 3C3F786D6C
HTML (html) 68746D6C3E
Email [thorough only] (eml) 44656C69766572792D646174653A
Outlook Express (dbx) CFAD12FEC5FD746F
Outlook (pst) 2142444E
MS Word/Excel (xls.or.doc) D0CF11E0
MS Access (mdb) 5374616E64617264204A


相關文章