MemoryError

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
Benutzeravatar
Mawilo
User
Beiträge: 452
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Hallo,

ich möchte eine ziemlich große Datei (590 MB) in ein Unix-Format bekommen. Dazu verwende ich folgenden Code:

Code: Alles auswählen

binfile = file(f_new,'rb')
bin = binfile.read()
binfile.close()
bin = bin.replace('\r\n','\n')
binfile = file(f_new,'wb')
binfile.write(bin)
binfile.close()
Leider bekomme ich folgende Fehlermeldung:

Code: Alles auswählen

File "D:\Dokumente und Einstellungen\Eigene Dateien\Programme\FAM-Tool\change_dat.py", line 239, in replace_date
    bin = bin.replace('\r\n','\n')
MemoryError
Ich denke, mein Arbeitsspeicher reicht für so eine große Datei nicht aus. Gibt es eine Möglichkeit, das auch etwas ressourcenschonender hinzubekommen?

Stephan
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

mit binfile.read() liest du dir 590MB komplett ein! Der Memory Error ist also kein Wunder ;)

Mach es doch einfach Blockweise... Du kannst bei read() auch die Anzahl der Bytes angeben...

Aber warum öffnest du es eigentlich im Binary Modus, wenn du Zeilenende-Zeichen konvertieren willst???

Geht's nicht auch im universal newline Modus, also mit file(f_new,'rU') ? Dann könntest du mit readline() arbeiten...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Ungetestet:

Code: Alles auswählen

infile = open('oldname', 'rU')
outfile = open('newname', 'w')
outfile.writelines(infile)
outfile.close()
infile.close()
Benutzeravatar
Mawilo
User
Beiträge: 452
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Ich habe es mal mit dem blockweisen Einlesen der Datei probiert. Funktioniert ganz gut.

Code: Alles auswählen

import os
f = file(datei,'rb')
f_new = file('test.xml','wb')

filesize =  os.stat(datei)[6]
z = 0
print 'Dateigroesse: %s byte'%filesize
while filesize > 0:
    z = z + 1
    print 'Block %s wird gelesen'%z
    bin = f.read(30000000)
    bin = bin.replace('\r\n','\n')
    print 'Block %s wird geschrieben'%z
    f_new.write(bin)
    f_new.flush()
    filesize = filesize - 30000000
    print 'Noch zu lesende Dateigroesse: %s byte'%filesize

f.close()
f_new.close()
Der Code bekommt bestimmt keinen Schönheitspreis aber er erfüllt seinen Zweck :)

Stephan
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Wobei theoretisch ein Fehler sich einschleichen kann :( Wenn nämlich die kombination "\r\n" genau am BlockEnde/Anfang getrennt werden! Dann klappt die replace-Regel nicht mehr.
Wobei mir dafür spontan nur die Lösung einfällt, ein .replace("\r","") zu machen... Wenn keine einzelnen "\r"'s vorkommen, geht's so auch...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten