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

MemoryError

Beitragvon Mawilo » Donnerstag 7. Juli 2005, 13:17

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
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Re: MemoryError

Beitragvon jens » Donnerstag 7. Juli 2005, 13:41

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...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Re: MemoryError

Beitragvon BlackJack » Donnerstag 7. Juli 2005, 22:11

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: 446
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Beitragvon Mawilo » Donnerstag 7. Juli 2005, 22:17

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
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Freitag 8. Juli 2005, 06:06

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...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder