C Beliebig große Dateien einlesen

Crazy Driver

Ensign
Registriert
Jan. 2011
Beiträge
182
Hallo,

Ich wollte gerne wissen, wie ich in C beliebig große Dateien einlesen kann.
Bei mir sind es max. 3 gb, die ich einlesen kann. Dann hab ich keinen Arbeitsspeicher mehr frei.
Gibt es denn vielleicht irgendeine Möglichkeit, Dateien zu öffnen, die größer als 10 gb sind?
 
Was genau machst du denn, dass du dafür die gesamte Datei auf einmal im Speicher haben musst?
Unter welchem Betriebssystem läuft das Programm genau?
 
Du kannst natürlich nicht mehr Datei im Speicher haben als du überhaupt Speicher verfügbar hast. Das heißt entweder du liest die Datei stückweise aus oder du lagerst gerade nicht benötigte Daten aus, zum Beispiel in temporäre Dateien.
 
An die temporäre Auslagerung hab ich garnicht gedacht!
Werde es damit versuchen!
 
was du nutzen könntest nennt sich "memory mapped files".

damit kannst du über den virtuellen adressraum eine datei wie einen grossen arbeitspeicher (größer als dein tatsächlicher) ansprechen und dabei wird automatisch auf den richtigen abschnitt innerhalb der datei verwiesen.

google danach. gibt's in C schon ewig. windows hat dazu paar eigene verschlimmbesserungen aufgesetzt, die du eher vermeiden solltest, wenn du kannst.

edit: alternativ, falls der virtuelle adressraum sogar überschritten wird (was eigentlich bei den neusten OS kaum möglich ist) bleibt dir nur selbst eine verwaltung zu schreiben mit der du quasi blockweise auf die datei zu greiffst. ganz passt sie aber dann so doer so nicht in den abreitsspeicher.
 
Ich glaube du machst da ganz grundsätzlich etwas falsch. Eine große Datei lesen heißt _nicht_, dass du sie einfach komplett in den Arbeitsspeicher einliest!
 
Nochmal die Frage - warum möchtest du das überhaupt? Klingt nicht wirklich danach, als wenn das Sinn machen würde, was du da vor hast. Wenn du erklärst, warum du das überhaupt machen möchtest, könnte man dir sicherlich besser weiterhelfen. ;)

Mit nacktem C könntest du übrigens je nach Implementierung der Standard-Library Probleme kriegen. Da empfehlen sich sonst die nativen Windows-APIs, insbesondere auch für Memory Mapped Files.
 
Hat er eigentlich je von Windows gesprochen? Nur, weil ihr das alle so einfach annehmt.

Außerdem gebe ich euch natürlich Recht, dass es in der Regel unnötig ist, eine große Datei komplett im Speicher zu haben.
Die Stückchen, die man gerade benötigt herauszulesen, sollte ja wohl gehen.
Sonst ist das Dateiformat für den Arsch und man sollte das mal gründlich überdenken.
 
Guter Einwand! Hab mich von der Windows-Liste verwirren lassen. Aber da die Frage schon gestellt wurde und keine Antwort kam... nun gut. :)
 
Unter einem 64Bit-OS mit einem 64Bit-Dateisystem und einem 64Bit-C-Compiler geht es. Wenn die Datei aber größer als der physische Arbeitsspeicher ist, wirst du nicht viel Freude damit haben.
Übrigens, memory mapped files sind kein Feature von C (oder C++) sondern vom Betriebssystem. Sie würden in dem Fall auch nicht helfen, da der virtuell adressierbare Speicherbereich nicht vergrößert wird. Ob die Datei beim Einlesen zu groß ist oder beim Mappen in den Adressraum ist am Ende unerheblich. Der einzige Unterschied ist, dass man sich bei memory mapped files die Lesezugriffe vom Betriebssystem abnehmen läßt.
 
memory mapped files sind in der POSIX spezifikation.

es geht auch nicht darum das der virtuelle adressraum vergrößert wird,sondern darum, dass man im allgemienen mehr virtuellen adressraum hat, als man arbeitsspeicher zur verfügung hat. die datei passt nicht in den arbeitsspeicher aber dank memory mapped files kann man auf die datei so zugreifen, als wäre sie komplett im speicher.

und nein auch bei betriebsystemen, die keine memory mapped files unterstützen (welches es allerdings kaum gibt) kann man dennoch memory mapped files benutzen mit entsprechender bib. memory mapped files bedarf prinzipiell keine unterstützung des os! jedes unix derivat und windows bietet es allerdings bereits.
 
Dese schrieb:
memory mapped files sind in der POSIX spezifikation.
Und POSIX bezeichnet eine C-API, keine C-Standardbibliothek. Aber prinzipiell ist das auch Interpretationssache, da die Grenzen zwischen C-Standard und Original UNIX-API (und POSIX) nicht sehr scharf gezogen sind ;-)

Dese schrieb:
es geht auch nicht darum das der virtuelle adressraum vergrößert wird,sondern darum, dass man im allgemienen mehr virtuellen adressraum hat, als man arbeitsspeicher zur verfügung hat. die datei passt nicht in den arbeitsspeicher aber dank memory mapped files kann man auf die datei so zugreifen, als wäre sie komplett im speicher.

Nunja, wenn man nur 4GB virtuellen Adressraum zur Verfügung hat, kann man trotzdem keine 10GB große Datei in den Speicher abbilden. Das meinte ich damit, als ich schrieb, dass memory mapped files im geschilderten Fall nicht helfen würden. Andersherum ist es genauso, wenn man genug virtuellen Adressraum hat, um die Datei im Speicher komplett abzubilden, kann man diesen Speicher auch explizit anfordern und selber die Datei dorthin lesen. Natürlich mit mehr Programmieraufwand und schlechterer Performance ;-)

Dese schrieb:
und nein auch bei betriebsystemen, die keine memory mapped files unterstützen (welches es allerdings kaum gibt) kann man dennoch memory mapped files benutzen mit entsprechender bib. memory mapped files bedarf prinzipiell keine unterstützung des os! jedes unix derivat und windows bietet es allerdings bereits.

Prinzipiell hast du da recht und weitere Diskussion wäre Haarspalterei. Meiner Erfahrung nach leiten die meisten Bibliotheken ihre Implementierung von memory mapped files eh ans OS weiter.
 
na gut. dann hat sich das ja geklärt. glaub wir haben uns ein wenig missverstanden meinen aber wohl in jedem punkt das gleiche. besser so als andersrum ;)
 
Memory Mapped Files sind eigentlich etwas, das man nur für sehr spezielle Zwecke einsetzt. Um eine "normale" Datei einzulesen ist es unsinnig MMF zu verwenden. Man setzt die z.B. ein um Binaries zu laden (DLLs, EXEs, ..), damit man sie über Sections einfach über alle Prozesse systemweit mappen kann.
Fast alle anderen Dateien werden über ganz normales I/O eingelesen.

Ich vermute mal der Threadersteller hat nicht verstanden, dass man innerhalb einer Datei auch nur einzelne Abschnitte auslesen kann -> fseek() ! Eine große Datei wird nur in den allerseltendsten Fällen komplett eingelesen.
 
Zurück
Oben