Problem bei file.read()

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
Roman
User
Beiträge: 65
Registriert: Dienstag 14. März 2006, 09:10
Wohnort: Berlin

Hallo,
ich habe folgendes Problem beim Lesen eines Files:
Mittels der Blowfish-Verschlüsselung (crypto-Modul) habe ich einen Text verschlüsselt und in eine Datei geschrieben. Wenn ich nun versuche, diese zu lesen, wird nicht die gesamte Datei gelesen, sondern nur ein Teil.

Beispiel:

Code: Alles auswählen

filehandle = file(path, 'w+')
filehandle.write(encrypted)
print "print len(coded) = ", len(coded)
filehandle.seek(0)
print "len(f.read()) = ", len(f.read())
Ausgabe:

Code: Alles auswählen

>>> len(coded) =  171
>>> len(f.read()) = 154
Der Anfang vom Gelesenen ist noch gleich, es fehlt nur am Ende etwas.

Kann es nun sein, dass zufällig der verschlüsselte Text die gleichen Zeichen wie das EOF hat? Denn wenn ich in Unicode lese, wird die gesamte Datei gelesen, allerdings ist hier das Problem, dass das Encoding nicht richtig ist.

Die Python-Doku schreibt dazu:
"Also note that when in non-blocking mode, less data than what was requested may be returned, even if no size parameter was given."

Allerdings habe ich keine Ahnung, wie ich im "blocking"-mode lesen kann, oder wie ich nach EOF weiterlesen kann, auch wenn das laut Doku möglich sein soll.

Oder kann es an etwas komplett anderem liegen?

Danke für alle Antworten, ich weiß echt nicht mehr weiter,
Roman

PS: Entschuldigt die Anglizismen... :wink: [/code]
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Ich hatte Probleme, wenn eine Datei im Modus "a" zuerst beschrieben und dann gelesen wurde. Beim Lesen hatte ich lauter kryptische Symbole und keine Ansii-Datei mehr.
Versuch es mal so:

Code: Alles auswählen

filehandle = file(path, 'w+')
filehandle.write(encrypted)
filehandle.close()
print "print len(coded) = ", len(coded)
filehandle.seek(0)
f = open(path)
print "len(f.read()) = ", len(f.read())
f.close()
Vllt ist auch an deiner ganzen Logik oder an den Variablennamen was falsch. Zuerst hast du die Variable ``filehandle``, dann machst du aber ``f.read()``. Und du schreibst ``encrypted`` in die Datei und vergleichst mit ``len(coded)``. Mir kommt das alles ein bisschen undurchsichtig vor.
BlackJack

@Roman: Ich rate einfach mal das Du unter Windows arbeitest. Das macht unterschiede zwischen Textdateien und Binärdateien. Wenn Du binäre Daten hast, die wirklich 1:1 Byte für Byte in einer Datei landen sollen oder auch so wieder ausgelesen werden sollen, dann *musst* Du die Dateien im Binärmodus öffnen.

Sonst ändert Dir Windows einige Bytes/Bytekombinationen (Zeilenenden) und hört beim Lesen bei einem bestimmten Byte-Wert, den das Betriebssystem CP/M als Textende-Markierung verwendet, einfach auf. DOS basiert auf CP/M und Windows basiert(e) auf DOS, darum machen die diesen Quatsch auch heute noch. :roll:
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

hört beim Lesen bei einem bestimmten Byte-Wert, den das Betriebssystem CP/M als Textende-Markierung verwendet, einfach auf.
Hat also nur Windows eine Art "EOF" Zeichen? Afaik gibt es dieses Zeichen unter Unix Rechnern gar nicht und ist nur ein Alias für -1, welcher als Rückgabewert von den einem Stream, zumindest in der C Stdlib, zurückgebenen wird bei Antreffen des Dateiendes.
BlackJack

Jup, Windows hört beim ersten treffen auf den Bytewert 26 in Textdateien auf zu lesen und C liefert dann -1 als EOF zurück.

Das geht zurück auf CP/M. Das Betriebssystem hat Dateien immer in 128 Byte Blöcken verwaltet und nirgends die tatsächliche Dateilänge gespeichert. Für Textdateien gab's deshalb die Konvention das Ende des Textes mit dem Bytewert 26 zu markieren.
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Ok, Danke :)
Roman
User
Beiträge: 65
Registriert: Dienstag 14. März 2006, 09:10
Wohnort: Berlin

Hallo,
danke für die zahlreichen Antworten...
Der code ist wirklich etwas undurchsichtig, muss ich zugeben :oops:, aber ich hatte in einiger Eile in der Bücherei zusammengetippt und teilweise Quelltext und teilweise eigenes verwendet.
Aber auf jeden Fall stimmen die Variablen und filehandles.
Hm, eigentlich wollte ich die Dateien gerade nicht unbedingt binär lesen, aber anscheinend bleibt mir nix anderes übrig, wenn ich wirklich 1:1 den Inhalt haben will. Schon etwas seltsam gemacht, dass das EOF zufällig in der Datei vorkommen kann...

@ ice2k3:
mit dem w+ Modus hatte ich es auch schon probiert, hat aber auch nicht geklappt. :cry:

Danke für die Antworten, ich probiers jetzt mal aus und melde mich, ob es gelungen ist.

Roman
BlackJack

@Roman: Warum willst Du eine Binärdatei nicht im Binärmodus lesen!? Das da zufällig auch das "Windows-EOF-Zeichen" drin vorkommen kann ist nicht komisch, weil Binärdaten nun mal grundsätzllich alle Bytewerte von 0 bis 255 enthalten können. Komisch wäre, wenn Blowfish genau diesen Wert grundsätzlich *nicht* erzeugen würde.

Und Du musst die Datei auch im Binärmodus *schreiben*, denn genauso wie das "EOF" kann natürlich auch das '\n'-Byte vorkommen und da macht Windows beim Schreiben im Textmodus zwei Bytes draus. Wenn Du das dann im Binärmodus liest, stimmt die Länge wieder nicht überein. Also falls Du schon geschriebene Daten hast, dürften die höchstwahrscheinlich "kaputt" sein.
Antworten