Potřebuji přečíst obsah jednoho souboru ze zip souboru, který je navíc chráněn heslem. Kvůli tomu heslu nelze použít zipfile, takže se snažím použít (v linuxu) program unzip s parametrem -p (vypíše obsah do pipe - stdout) a to tak, že zavolám popen(cmd).read(), toto funguje, ale problém je v tom, že textový soubor, který rozbaluji je v kódování cp1250 a nedaří se mi žádným způsobem ho tak přečíst :(
Zkoušel jsem knohovnu codecs, různý způsob konverzí, readstream, ale nic nechodí
Pokud soubor rozbalím do souboru na disku a otevřu až ten, tak to chodí bez problému (codecs.open()), ale tomu bych se rád vyhnul.
Naťukne mne někdo na správnou cestu?
Fórum › Python
Kódování výstupu procesu volaného pomocí popen
To geon:
tenhle převod jsem zkoušel jako první, bohužel to ale končí chybou
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfd' in position 8: ordinal not in range(128)
Úsek kódu vypadá takto:
cmd = string.join(["unzip -p -P", self.password, fName, self.vypisyName])
out = commands.getoutput(cmd)
print unicode(out, "cp1250")
podle mého se to už do toho prvního načte ve špatném kódování (jako utf8 které mám nastavené v prostředí?) a pak ten převod selže
zkoušel jsem např. i toto:
csv = os.popen(cmd,'rb')
csv = codecs.getreader("cp1250")(csv)
print csv.read()
se stejnou chybou
To geon:
Tohle už jsem rovněž zkoušel. Výsledek:
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 8-13: unsupported Unicode code range
Když pustím unzip samotný v terminálu, tak se to taky nevypíše v pořádku, což bych i očekával.
Je nějaký způsob jak zjistit v jakém kódování daný řetězec je?
Jediný rozdíl s tím převodem z utf8 je ten, že když ještě přidám parametr "ignore" pro ignorování chyb, tak ten příkaz projde, ale jsou pryč znaky nad 128. Když konvertuju z cp1250 tak i s ignorováním to hodí chybu.
Moje locale:
LANG=cs_CZ.UTF-8
LC_CTYPE="cs_CZ.UTF-8"
LC_NUMERIC="cs_CZ.UTF-8"
LC_TIME="cs_CZ.UTF-8"
LC_COLLATE="cs_CZ.UTF-8"
LC_MONETARY="cs_CZ.UTF-8"
LC_MESSAGES="cs_CZ.UTF-8"
LC_PAPER="cs_CZ.UTF-8"
LC_NAME="cs_CZ.UTF-8"
LC_ADDRESS="cs_CZ.UTF-8"
LC_TELEPHONE="cs_CZ.UTF-8"
LC_MEASUREMENT="cs_CZ.UTF-8"
LC_IDENTIFICATION="cs_CZ.UTF-8"
LC_ALL=cs_CZ.UTF-8
Kodování řetězce se dá zjistit těžko, ale kodování souborů to víceméně jde. Enca a file. Zkus to uložit do souboru a zjistit, v jakém kodování to máš. Možná, že na Linuxech to bude iso-8859-2, ale to jen hádám.
V nejhorším zkus použít file-like objekty, jako StringIO, když ti funguje, jak jsi psal, převod přes soubor.
To geon:
tak nakonec zafungovalo třeba tohle:
cmd = string.join(["unzip -bp -P", self.password, fName, self.vypisyName])
out = commands.getoutput(cmd)
print out.decode("cp1250")
ale funguje i hned ten první návrh...
problém byl s tím print, které neumí pracovat s unicode, takže pak samo převádí řetězec na kódování os.getdefaultencoding(), což je defaultně ascii a proto ta chyba se znaky nad 127. Dle http://www.diveintopython.org/xml_processing/unicode.html jsem zjistil, že nemám nastavené defaultní kódování v pythonu, takže bylo použito právě ascii, stačilo tedy přidat soubor sitecustomize.py do adresáře pythonu a nastavit v něm kódování na utf8 a už to maká. Ještě jsem zjistil, že se dá ten řetězec vypsat po enkódování na utf8 ručně, takže pak poslední řádek vypadá
print out.decode("cp1250").encode("utf8")
a jede to taky.
I tak ale díky za rady :)
Zjistit počet nových příspěvků
Přidej příspěvek
Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
Uživatelé prohlížející si toto vlákno
Uživatelé on-line: 0 registrovaných, 29 hostů
Podobná vlákna
Kódování XML výstupu z DB — založil dejnozka
Ukončení procesu pomocí skriptu — založil kenanab
Nahrávání výstupu pomocí Wasapi bez podpory zvukovky — založil honza15
Vstup/výstup do souboru v kódování UTF-8 pomocí C++ — založil flukas
Stratena metoda objektu v poli volaneho premennou — založil Smokie
Moderátoři diskuze