Datei umcodieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
kruphi
User
Beiträge: 21
Registriert: Donnerstag 25. Juli 2013, 14:57

Moin moin,


ich muss eine Datei umcodieren. Diese ist im Format UTF-8 codiert und ich muss diese in Latin-1 codiert haben.
Ist es sinnvoll die Datei dafür komplett einzulesen und dann neu zu speichern?
Bleiben dabei alle Zeichen komplett so erhalten?

Vielen Dank
BlackJack

@kruphi: Ja das ist sinnvoll, es sei denn die Datei(en) würden nicht in den Arbeitsspeicher passen. Ob alle Zeichen erhalten bleiben hängt davon ab ob die Originaldatei nur Zeichen enthält die auch in der Zielkodierung enthalten sind. Also wenn Du Pech hast, dann geht es nicht verlustfrei.
kruphi
User
Beiträge: 21
Registriert: Donnerstag 25. Juli 2013, 14:57

Ich habe ein paar Versuche jetzt hinter mir.
Ich hatte mir das einfacher vorgestellt.

hier mal einer meiner Versuche.

Code: Alles auswählen

import pickle
file = open("import-utf.txt", "r")
all=pickle.load(file).encode("latin-1")
file.close()
speicher = open("test.dta", "w") 
pickle.dump(all, speicher)
speicher.close()	

Vielen Dank
BlackJack

@kruphi: Wie kommt denn *pickle* da jetzt plötzlich ins Spiel? Das sind keine Textdateien. Selbst die, die nur ASCII-Werte verwenden muss man im Binärmodus öffnen, weil sie sonst kaputt gehen können, beziehungsweise nicht mehr plattformunabhängig sind.

Da können nahezu beliebige Python-Objekte serialisiert drin gespeichert sein, die darf man nicht einfach komplett als Datei umkodieren. Du musst schon wissen was da drin steckt, entpicklen, gezielt die Zeichenketten in den Objekten umkodieren, sofern man da einfach heran kommt, und dann wieder picklen.

Umkodieren bedeutet ausserdem dass man erst mit einer Kodierung dekodiert und dann mit der neuen kodiert. Nur in eine Richtung funktioniert das nicht.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

kruphi hat geschrieben:Ist es sinnvoll die Datei dafür komplett einzulesen und dann neu zu speichern?
Anders geht es wohl nicht.

Code: Alles auswählen

import io

sourcefile = 'test-utf8.txt'
targetfile = 'test-latin1.txt'

with io.open(sourcefile, mode='r', encoding='UTF-8') as f_in, \
      io.open(targetfile, mode='w', encoding='LATIN-1') as f_out:
    for line in f_in:
        f_out.write(line)
Falls du die Daten allerdings wirklich im pickle-Format vorliegen hast, dann ist der gesamte Ansatz schon falsch.
BlackJack

@/me: Natürlich geht es anders, Du machst es doch selber vor. Oder ich habe *komplett einlesen* jetzt falsch gedeutet. :-)
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

BlackJack hat geschrieben:@/me: Natürlich geht es anders, Du machst es doch selber vor. Oder ich habe *komplett einlesen* jetzt falsch gedeutet. :-)
Gelesen wird die Datei natürlich schon komplett, allerdings müssen natürlich nicht alle Teile gleichzeitig im Hauptspeicher sein.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@me: Wieso benutzt Du das ``open`` aus dem ``io``-Modul? Ist mir gerade nicht klar.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Hyperion hat geschrieben:@me: Wieso benutzt Du das ``open`` aus dem ``io``-Modul? Ist mir gerade nicht klar.
Kompatibilität zwischen Python 2 und Python 3.
Dami123
User
Beiträge: 225
Registriert: Samstag 23. Februar 2013, 13:01

Könnte man nicht die eingebauten Funktion "encode" und "decode" verwenden?

Code: Alles auswählen

with open(os.path.join("file"), "r+") as datafile:    
    content = datafile.read().decode("utf-8").encode("latin-1")
    datafile.seek(0)
    datafile.write(content)
BlackJack

@Dami123: Das sind Methoden und keine Funktionen, aber ja, das könnte man auch.

Aber das was Du mit der Datei da machst ist kaputt. Das könnte man beim umgekehrten Weg machen, aber so herum wird bei jeder Datei die diese Umwandlung tatsächlich *braucht* am Ende der Datei noch etwas von der alten Datei stehen was da nicht hingehört.

Und das ``os.path.join("file")`` ist sinnfrei.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Dami123: Außerdem solltest Du die Datei binär öffnen ("rb") um eine Interpretation des Inhalts zu verhindern, da das Umwandeln von Bytes in Text schon durch das "decode" geschieht.
Dami123
User
Beiträge: 225
Registriert: Samstag 23. Februar 2013, 13:01

@BlackJack
Was ist den eine geeignete Variante um eine Datei zu lesen und schreiben, ohne sie zweimal zu öffnen?

@Sirius3
Ok.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Warum haelst du es denn fuer erstrebenswert die Datei nur einmal zu oeffnen?

Das Problem, das BlackJack beschreibt, hat nicht wirklich etwas damit zu tun, dass man die Datei zweimal oeffnen sollte. Vielmehr wird beim Oeffnen mit dem 'w' Flag eine moeglicherweise existierende Datei geloescht/ueberschrieben.
Ein `file.truncate(0)` nach dem `file.seek(0)` hat das gleiche Ergebnis. Alternativ auch ein `file.truncate()` nach dem Schreiben.

Kommt es aber zu irgendeinem Fehler, hat man unwiederbringlich Datensalat. Darum sollte man in eine andere Datei schreiben und die danach gegebenenfalls zur urspruenglichen Datei umbenennen.
Dami123
User
Beiträge: 225
Registriert: Samstag 23. Februar 2013, 13:01

Alles klar, denke werde weiterhin die zweimal öffnen Methode nutzen.
kruphi
User
Beiträge: 21
Registriert: Donnerstag 25. Juli 2013, 14:57

Wollte mich nur noch einmal bedanken!
Hat wunderbar geklappt. Habe mich jetzt auch noch einmal mit pickle beschäftigt.... :oops:


Vielen Kruphi
Antworten