V jakém kódování je soubor uložen?
Tak buď se ptáme na název (jméno) souboru nebo na vlastní text, který je v souboru uložen.
Kódování jména souboru
se dá zjistit vcelku jednoznačně: sys.getfilesystemencoding( ). Jen pro doplnění, pokud funkci os.listdir() předáme parametr v Unicode, bude vrácený seznam taky v Unicode.
Kódování obsahu souboru
Kódování obsahu souboru se nedá (až na pár vyjímek ???) určit zcela jednoznačně. S vysokou mírou pravděpodobnosti se však to dá odhadovat. Více o tom na PythonUnicodeCestina. Na tento odhad existují různé prográmky (enca, file).
Následující script v Pythonu je jistě jejich slabým odvarem, přesto je náš, malý a funkční:
# -*- coding: utf-8 -*-
import os, sys
def odhadKodovani(text):
""" Funkce na urceni (odhad) kodovani textu v souboru.
První výběr: která kodování projdou při převodu na unicode, ty by to mohly být.
Většinou jich je ale několik. Ukládají se jako instance do seznamu.
Druhý výběr: Prochází se seznam platných kodování z prvního výběru a pro každé se zjišťuje,
kolik je v textu českých znaků. To, které jich má nejvíce, bude velmi pravděpodobně
hledané kodování.
"""
encodings = (
'ascii',
'iso-8859-2',
'cp1250',
'cp852',
'utf-8'
)
cestina=u"áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ" # snad jsem na žádné nabodeníčko nezapomněl
class enc:
u"Třída validních kodování"
def __init__(self, kodovani):
self.kodovani=kodovani # typ kodovani
self.pocet=0 # kolik je v textu českých znaků
# ------ první výběr ------------------------------------------------------
encoding = []
for e in encodings:
try:
unicode(text,e)
except (UnicodeEncodeError, UnicodeDecodeError):
pass
else:
encoding.append(enc(e)) # přidám do seznamu instanci s platným kodovaním
# ---- druhý výběr ---------------------------------------------------------
max=-1 # pokud v textu nejsou ceske znaky, toto zajisti, ze se zvolí ascii (prvni v encodings)
for kod in encoding:
for znak in unicode(text,kod.kodovani):
if znak in cestina:
kod.pocet=kod.pocet+1
if kod.pocet>max:
max=kod.pocet
maxKod=kod.kodovani
return maxKod
if __name__=="__main__":
print u"Test všech souborů v aktuálním adresáři:\n", "-"*40
seznam =[jmeno for jmeno in os.listdir('.') if os.path.isfile(jmeno)]
for jmeno in seznam:
text=file(jmeno).read()
print jmeno, odhadKodovani(text)