2013-02-28 12 views
8

Plik jest w zasadzie plikiem XML, więc mógłbym użyć ciągu <?xml (lub reprezentacji heksadecymalnej: '3c 3f 78 6d 6c') jako magicznej liczby, ale istnieje kilka przeciwnych powodów, aby tego nie robić, jeśli na przykład są dodatkowe białe przestrzenie to może przerwać to czekanie.Jak mogę powiedzieć, że plik jest SVG bez użycia magicznej liczby?

Inne obrazy, których potrzebuję/oczekuję do sprawdzenia, to wszystkie pliki binarne i magiczne numery. Jak mogę szybko sprawdzić, czy plik jest w formacie SVG, bez korzystania z rozszerzenia w końcu za pomocą Pythona?

+0

jak o przeczytaniu początku pliku jako binarne - jeśli nie można znaleźć żadnych magicznych liczb, można przeczytać ją jako tekst i spróbować dopasować go do znanych wzorców tekstowych? – dmg

+0

@DJV Brzmi rozsądnie. I nie widzę, jak to się nie mogło złamać. –

Odpowiedz

10

XML nie musi zaczynać się od preambuły <?xml, więc testowanie tego prefiksu nie jest dobrą techniką wykrywania - nie wspominając, że identyfikuje każdy XML jako SVG. Przyzwoity wykrywania i bardzo proste do wykonania, jest użycie prawdziwego XML parser, aby sprawdzić, czy plik jest dobrze uformowane XML, który zawiera element svg najwyższego poziomu:

import xml.etree.cElementTree as et 

def is_svg(filename): 
    tag = None 
    with open(filename, "r") as f: 
     try: 
      for event, el in et.iterparse(f, ('start',)): 
       tag = el.tag 
       break 
     except et.ParseError: 
      pass 
    return tag == '{http://www.w3.org/2000/svg}svg' 

Korzystanie cElementTree zapewnia, że ​​detekcja jest sprawne dzięki wykorzystaniu ekspata; timeit pokazuje, że plik SVG został wykryty jako taki w ~ 200μs, a nie-SVG w 35μs. Interfejs API iterparse umożliwia parserowi zrezygnowanie z tworzenia całego drzewa elementów (bez względu na nazwę modułu) i odczytuje tylko początkową część dokumentu, niezależnie od całkowitego rozmiaru pliku.

+1

Po przeczytaniu pytania połączenie liczb magicznych binarnych i XML wywołało czerwony alert. Ta odpowiedź wyjaśnia, że ​​parsowanie formatu binarnego wymaga jednego podejścia, a odczytywanie XML (tekstowego) wymaga CAŁKOWICIE RÓŻNEGO podejścia. – heltonbiker

+2

@heltonbiker Dokładnie. Magiczne liczby mają dla nich jedno: surowa wydajność. Dlatego odpowiedź zawiera próbkę kodu, która demonstruje * efektywną * implementację proponowanego podejścia. – user4815162342

+0

Ponadto, jeśli dobrze rozumiem, plik binarny jest z natury niestrukturalny, na przykład plik tekstowy. W prostym tekście powinniśmy zatem uwzględnić shebangi, doctypy itd., Podczas gdy binary potrzebują tych zwięzłych, tajemniczych liczb magicznych. Sądzę, że w tym sensie ten magiczny numer przypomina najmniejszy rozmiar - możliwy, niskopoziomowy "stary sposób" przechowywania danych do plików, podczas gdy XML i JSON, żeby wymienić tylko kilka, są bardziej nowoczesne, czytelny, zawyżony i nadmiarowy sposób przechowywania danych w plikach. Oba podejścia różnią się zatem w więcej niż jednym aspekcie. – heltonbiker

2

Można spróbować czytanie początek pliku jako binarne - jeśli nie można znaleźć żadnych magicznych liczb, można przeczytać ją w postaci pliku tekstowego i mecz jakichkolwiek wzorców tekstowych chcesz. Lub odwrotnie.

Powiązane problemy