Seite 1 von 1
file.read()-Größe automatisch einsetzen
Verfasst: Donnerstag 16. November 2017, 17:05
von DMD-OL
hey ho,
wie bekomm ich die größe einer datei, die ich dann in file.read() verwenden kann?
ich verwende eine Beispieldatei in der nur "Hallo, na wie gehts?" steht.
Damit funktioniert alles:
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-
import time
import numpy as np
import csv
import os
desktopFile = os.path.expanduser("~\Desktop")
path_grund = desktopFile+'\Handy-Datenbank'
path_folder = path_grund+'\\Beispiel.001'
filesize = os.stat(path_folder).st_size
print filesize
f = open(path_folder, 'rb')
def count(f):
while 1:
block = f.read(filesize)
if not block:
break
yield block.split(";")
linecount = count(f)
print next(linecount)
Zum weiteren Testen größerer Dateien benutze ich eine DATANORM.001-Datei (schon ziemlich groß

)
Damit funktioniert es nicht

ich bekomme ein Exception:
Code: Alles auswählen
Message File Name Line Position
Traceback
<module> C:\Users\DMD-OL\Desktop\Handy-Datenbank\Einlesen.py 25
count C:\Users\DMD-OL\Desktop\Handy-Datenbank\Einlesen.py 19
exceptions.MemoryError
Als Größe der DATANORM.001 wird 325315663 (bytes?) angegeben.
Was ist da falsch?
Re: file.read()-Größe automatisch einsetzen
Verfasst: Donnerstag 16. November 2017, 17:40
von noisefloor
Hallo,
der Code ist... komisch. Was ist das Ziel der Aktion?
Gruß, noisefloor
Re: file.read()-Größe automatisch einsetzen
Verfasst: Donnerstag 16. November 2017, 17:48
von Sirius3
@DMD-OL: was für ein System hast Du, wo ein paar hundert Megabytes schon Probleme machen?
Dein Programm ist schon viel zu kompliziert. Pfade setzt man mit `os.path.join` zusammen. `filesize` kommt auf magische Weise in die Funktion `count`. `count` ist ein komischer Name, für das was die Funktion macht. `read` ohne Parameter liest schon die gesamte Datei, da braucht man also nicht erst umständlich die Größe ermitteln. Wenn man die ganze Datei liest, dann wird die while-Schleife exakt ein mal durchlaufen. Man sollte nicht Funktionsdefinitionen mit ausführbarem Code mischen. Dateien immer mit dem with-Statement öffnen.
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
def count(f):
block = f.read()
return block.split(";")
database_filename = os.path.expanduser("~/Desktop/Handy-Datenbank/Beispiel.001")
with open(database_filename, 'rb') as f:
linecount = count(f)
print linecount
Wenn die Daten nicht mehr in den Speicher passen, dann mußt Du wirklich blockweise lesen. Da ist dann die Gesamtgröße auch egal, denn Du rufst `read` mit einer sinnvollen Blockgröße auf.
Re: file.read()-Größe automatisch einsetzen
Verfasst: Freitag 17. November 2017, 17:41
von DMD-OL
ich hab eine riesige DATANORM.001-Datei.
und ich versuche die einfach in eine datenbank zu schreiben bzw. nur erst einmal zu printen.
daher lese ich die datei ein und versuche durch den yield-befehl alles auszulesen, ohne extra in den speicher, ohne memory(?), zu schreiben.
wie kann man eine text-datei den blockweise lesen? da brauch man doch sowas wie:
block = f.read(anfang,ende)
oder noch besser
block = f.readline(anfang,ende) --> so was wär richtig geil

lg
Re: file.read()-Größe automatisch einsetzen
Verfasst: Freitag 17. November 2017, 18:04
von snafu
Du musst das Ende der Datei für häppchenweises Lesen nicht kennen. Das Dateiobjekt hat einen Zeiger, der sich die aktuelle Position merkt. Bei
read(n) rutscht er um
n Stellen in Richtung Dateiende. Wenn er ganz am Ende steht, dann gibt
read(n) eine leere Zeichenkette zurück. Folglich kann man sowas machen:
Code: Alles auswählen
def read_chunks(f, size):
while True:
chunk = f.read(size)
if not chunk:
return
yield chunk
# oder alternativ:
def read_chunks(f, size):
return iter(lambda: f.read(size), '')
Re: file.read()-Größe automatisch einsetzen
Verfasst: Freitag 17. November 2017, 18:53
von noisefloor
Hallo,
daher lese ich die datei ein und versuche durch den yield-befehl alles auszulesen, ohne extra in den speicher, ohne memory(?), zu schreiben.
Mit `read` liest du aber in den Speicher. Und ich weiß ja nicht, welche Vorstellung du davon hast, was `yield` macht - aber es macht definitiv nicht das, was du dir denkst / erhoffst. In deinem Code macht es jedenfalls keinen Sinn.
Und du bist auf die Frage von Sirius3 nicht eingegangen: deine Datei ist ca. 325 MB groß - das ist nicht viel und erst recht nicht "riesig". Es ist doch seit mehreren Jahren Standard, dass Rechner mit 4 GB RAM haben. Oder machst du das am Raspi 1 oder Zero? Den wird es in der Tat eng...
Gruß, noisefloor