Probleme mit .read() bei großen files

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 Alle zusammen,

Ich habe folgendes Problem, wenn ich große binäre Dateien auslesen möchte:

Code: Alles auswählen

#test.py
f = file('C:\\test.mpg', "rb") #Datei ungefaehr 7 Mb gross
print f.tell()
print f
print f.read(). "hier sollte der Inhalt stehen"
f.close()
Die Ausgabe sieht dann so aus:

Code: Alles auswählen

>>> 
0
<open file 'C:\test.mpg', mode 'rb' at 0x00B92A80>
 hier sollte der Inhalt stehen

>>> 
Da ein print f mir ja auch zurückgibt, dass die Datei offen ist, habe ich gar keine Ahnung mehr, was falsch sein könnte... :?

Merkwürdig ist auch, dass das script funktioniert, wenn ich f.readlines() anstatt f.read() schreibe.
Ich würde mich sehr über Hilfe freuen. :)
Danke schon mal im Voraus für alle Antworten,
Roman
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Und wenn du es mit

Code: Alles auswählen

print f.read()
# statt
print f.read(). "hier sollte der Inhalt stehen"
probierst? Instbesondere der Punkt nach dem () sieht mir seltsam aus - kann es aber leider grade nicht testen, da meine Textkonsole den Geist aufgegeben hat *sigh*.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Code: Alles auswählen

f = file('C:\\test.mpg', "rb")
# f ist dein File_Objekt_ nicht den Inhalt der Datei!

print f.tell()

content = f.read()
print content

f.close()

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hi,

nein, das "Problem" hatte ich auch schonmal. Und zwar wurde bei unterschiedlichen Dateien unterschiedlich viel ausgegeben.

Daher bin ich überzeugt, dass es ein Binärcodezeichen gibt, ab dem die Print-Ausgabe abbricht. Versuch es mal mit:

Code: Alles auswählen

print map(ord, f.read(1000))
Damit kannst Du Dir die Inhalte der ersten 1000 (kannst auch eine andere Zahl wählen) Zeichen ausgeben lassen.

Grüße,
der Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Roman
User
Beiträge: 65
Registriert: Dienstag 14. März 2006, 09:10
Wohnort: Berlin

Hallo,

@ Leonidas: Bei dem Punkt habe ich mich wohl verschrieben, es sollte natürlich ein Komma sein. :oops:

Zu Michael Schneiders Lösung: Ich bekomme als Ausgabe eine Liste mit Zahlen und diese sieht mir nicht mehr nach binär-code aus.
Wenn ich z.B. eine .mp3 Datei einlese und dann in eine andere Datei schreibe, wäre das Ergebnis wieder abspielbar?
Und wie sieht das zeitlich aus mit dem auslesen? Dauert das nicht bei z.B. 50 mb eine halbe Ewigkeit, alles zu lesen und in eine Liste zu packen?

Also irgendwie sieht mir das auch so aus, als hätte read() irgendwie Probleme, die Datei zu lesen. Ich habe schon öfter aus binaries gelesen und das ging bis jetzt immer alles.

Danke schon mal im Voraus für alle weiteren Antworten,
Roman
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Mach mal

Code: Alles auswählen

print repr(f.read())
Dann gibt der die Sonderzeichen mit \xYZ aus.

Gruss
Nirven
User
Beiträge: 130
Registriert: Mittwoch 10. Mai 2006, 08:18
Wohnort: Bremerhaven

Ja, mir ist auch schon aufgefallen das gegen Ende der Datei gerne mal abgebrochen wird. Interessanterweise ist mir nie aufgefallen, dass das schon am Anfang passiert, immer irgendwo in den letzten paar hundert Zeilen (bei Logdatein mit zwanzig- bis dreißigtausend Zeilen). Daher war es mirt relativ egal.


@Roman: Wenn du die Datein im binär-Modus öffnest

Code: Alles auswählen

f = open('Dateiname.mp3', 'rb')
und später auch wieder so schreibst (also dann mit 'wb'), funktioniert es. Dann wird nichts umgewandelt sondern jedes einzelne Byte kopiert wie es ist.
bb1898
User
Beiträge: 200
Registriert: Mittwoch 12. Juli 2006, 14:28

Roman hat geschrieben:
Zu Michael Schneiders Lösung: Ich bekomme als Ausgabe eine Liste mit Zahlen und diese sieht mir nicht mehr nach binär-code aus.
Der Vorschlag hatte ein anderes Ziel: Du siehst so, welche Zeichen in der Datei stehen und kannst erkennen, ob ein Zeichen dabei ist, das die Ausgabe mit print zum Abbrechen bringen könnte. Ebenso bei dem Vorschlag von rayo.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hi,

danke bb1898. Sorry wenn ich mich unklar ausgedrückt habe. Der Test sollte nur zeigen, dass es wirklich noch weitergeht, auch wenn nichts weiter ausgegeben wird. Bitte den obigen Code nicht zum Kopieren verwenden. :-)

@Roman: Gegenfrage: wie sieht für Dich denn Binärcode aus?

Solang Du das "b" im Dateimodus nicht vergisst, werden die Daten schon richtig eingelesen und geschrieben. Zur Sicherheit kannst Du die Größen auch validieren:

Code: Alles auswählen

import os
sDateiName = "test.dat"
fileEingabe = open(sDateiName, "rb")
sBinaerString = fileEingabe.read()
fileEingabe.close()
if len(sBinaerString) == os.path.getsize(sDateiName):
    print "die Datei wurde erfolgreich eingelesen"
else:
    print "Fehler beim Einlesen, nur %i von %i Zeichen gelesen" % (len(sBinaerString), os.path.getsize(sDateiName))
Grüße,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Roman
User
Beiträge: 65
Registriert: Dienstag 14. März 2006, 09:10
Wohnort: Berlin

Hallo,

Nach langem hin-und herprobieren funktioniert es jetzt endlich.
Ich glaube, dass der Fehler darin bestand, dass print wohl einfach nichts mehr anzeigt, wenn die Datenmenge zu groß ist. (zumindest denke ich das jetzt, weil er den Inhalt der einen Datei in eine andere schreiben kann... Wenn man ihn sich halt nicht printen lässt!)

Danke noch mal für eure Mühe und die vielen Tipps,
Roman
Antworten