PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : wie öffne ich mehrere Dateien gleichzeitig


Asmodeus
2004-06-12, 11:26:00
Ich habe folgendes Problem, ich möchte unter C++ mit Hilfe von std :: ofstream mehrere Dateien öffnen, um Daten hinein zu schreiben. Leider ist bei ziemlich genau 510 offenen Dateien Schluss. Mehr Dateien lassen sich dann nicht mehr öffnen. Nun erscheinen mir 510 gleichzeitig offene Dateien nicht gerado so übermäßig viel. Gibt es also noch einen anderen Weg um eine größere Anzahl von Dateien gleichzeitig öffnen zu können?

Gruss, Carsten.

St@N
2004-06-12, 12:06:19
wieso öffnest du 510 dateien? kannst sie doch schließen und vorher die daten auslesen?
oder was fürn prog schreibstn?

Asmodeus
2004-06-12, 12:23:58
Original geschrieben von St@N
wieso öffnest du 510 dateien? kannst sie doch schließen und vorher die daten auslesen?
oder was fürn prog schreibstn?

Leider ist es nur so praktikabel. Es geht darum bis zu 10 GByte an Daten zu verwalten und abzuspeichern. Im Hauptspeicher kann ich das nicht machen. Ich habe aber den Vorteil, dass sich die Daten sehr gut in kleine Datengruppen unterteilen lassen (z.b. eben in 1000 Datengruppen). Nun wollte ich eben gleich 1000 Dateien öffnen (für jede Gruppe eine, da die Daten sowieso gruppiert abgespeichert werden müssen) und die Daten reinschreiben. Die Daten werden jedoch nicht lokal pro Gruppe generiert, sondern global, d.h. die Daten müssen nach der Generierung erst der jeweiligen Gruppe zugeordnet werden. Deshalb kann ich für jedes Datenpaket auch nicht immer erst die entsprechende Datei öffen, die Daten abspeichern und wieder schliessen. Das dauert bei bis zu 10 GByte an Gesamtdaten einfach viel zu lange. Darum will ich die Dateien eben schon alle offen haben, denn dann geht das Speichern wesentlich schneller.

Gruss, Carsten.

Asmodeus
2004-06-12, 12:33:36
Die ganze Sache wird genau genommen durch folgenden Umstand so kompliziert:

Bei Win 3.1 Win32s konnte man standardmäßig gleichzeitig nur etwa 20 FileHandle offen haben. Um die maximale Anzahl erhöhen zu können gab es den Befehl SetHandleCount(). Bei Visual Studio .NET 2003 gibt es für diesen Befehl nun folgende Aussage:
SetHandleCount: Not necessary and has no effect. There is no explicit file handle limit.
Ich frage mich nur, wenn es kein Limit gibt, wieso dann trotzdem bei 510 Schluss ist, und wieso es dann z.B. auch noch den Fehlercode ERROR_TOO_MANY_FILES_OPEN gibt.
Ohne Limit wäre meiner Meinung nach auch dieser Fehlercode überflüssig. :bonk:

Gruss, Carsten.

DocEW
2004-06-15, 11:21:01
Falls du keine Lösung findest, könntest du zumindest immer 510 offen halten. Wenn du dann in eine Datei schreiben mußt, die nicht offen ist, kannst du eine andere schließen und diese dann öffnen. Als Strategie kannst du z.B. diejenige schließen, die du am längsten nicht benötigt hast oder die du am wenigsten oft benutzt hast oder irgendwie sowas. Auch umgekehrt (zuletzt gebrauchte schließen) kann es sinnvoll sein, je nach typischem Verlauf deiner Anwendung.

Gast
2004-06-15, 14:10:02
Also ich habe das gerade mal probiert. Ich konnte völlig problemlos 10.000(!) Dateien öffnen:

for(int x=0;x<10000;x++){
name1 = _tempnam( "c:\\temp", "stq" );
ofstream out(name1);
out << name1 << x << "\n";
}

Gast
2004-06-15, 16:01:28
Hier noch ein Beispiel mit 10.000 geöffneten Dateien für die jeweils ein Handle vorliegt:

int main(int argc, char *argv[])
{
HANDLE hFile[10000];
char *name1;

for (int x=0;x<10000;x++){
name1 = _tempnam( "c:\\temp", "stq" );
hFile[x]=CreateFile(name1, GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);



}
for (int x=0;x<10000;x++)
CloseHandle(hFile[x]);


system("PAUSE");
return 0;
}

hmmmmmmm
2004-06-16, 01:56:34
lol Gast. Du prüfst ja gar nicht ob CreateFile auch erfolgreich war.

Gast
2004-06-16, 08:16:21
Original geschrieben von hmmmmmmm
lol Gast. Du prüfst ja gar nicht ob CreateFile auch erfolgreich war. Ich möchte ja auch nicht für Asmodeus die Software schreiben! ;)

Außerdem ist das, wie du an den fehlenden #include Statements sicher gesehen hast, auch nur ein Codefragment.

Aber selbstverständlich habe ich auf der Festplatte nachgeschaut, ob tatsächlich 10.000 Dateien angelegt wurden. Und ja, alle 10.000 Dateinnamen sind da!

Gast
2004-06-16, 14:57:19
So jetzt noch mal extrem mit 100.000 Handles und Fehlerprüfung! ;)

for (int x=0;x<100000;x++){
name1 = _tempnam( "c:\\temp\\temp", "stq" );
hFile[x]=CreateFile(name1, GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile[x]==INVALID_HANDLE_VALUE)
x=100000;


}
for (int x=0;x<100000;x++)
CloseHandle(hFile[x]);

Das Löschen der 100.000 Dateien hat übrigens länger gedauert, als das Schreiben des Codes!

ethrandil
2004-06-16, 15:42:34
Original geschrieben von Gast
Das Löschen der 100.000 Dateien hat übrigens länger gedauert, als das Schreiben des Codes!
Dann solltest du das auch noch automatisieren... :|

- Eth

Gast
2004-06-16, 15:50:19
Original geschrieben von ethrandil
Dann solltest du das auch noch automatisieren... :|

- Eth Dann würde das Schreiben des Codes ja wieder länger dauern als... ;)

Jedenfalls kommt mir das mit den 510 offenen Dateien komisch vor. Ich konnte auch gar nichts finden, weder auf MSDN noch Google oder sonstwo, wo etwas von so einer Beschränkung gestanden hätte.

Könnte das, obwohl es mir eigentlich unwahrscheinlich erscheint, am verwendeten Compiler liegen?

Asmodeus
2004-06-16, 16:40:28
Original geschrieben von Gast

Jedenfalls kommt mir das mit den 510 offenen Dateien komisch vor. Ich konnte auch gar nichts finden, weder auf MSDN noch Google oder sonstwo, wo etwas von so einer Beschränkung gestanden hätte.

Könnte das, obwohl es mir eigentlich unwahrscheinlich erscheint, am verwendeten Compiler liegen?

Ja, kommt mir inzwischen auch merkwürdig vor. Aber ich verwende ja nun mit Visual Studio C++ .NET 2003 nix exotisches, was den Compiler anbelangt.

Das komische ist ja auch, dass es auf zwei verschiedenen Rechner auftritt. Zum einen unter Visual Studio .NET 2003 mit normalem C++ und der Verwendung von ofstream. Und zum anderen tritt es aber auch unter Visual Studio .NET 2003 und der Verwendung von Qt und den Qt-eigenen File-Operatoren auf.

Gruss, Carsten.

Gast
2004-06-16, 16:49:31
Also ich hab es mit Dev-C++ kompiliert. VS2003 kann ich erst morgen ausprobieren.

Gast
2004-06-18, 14:24:51
So.

Habe es jetzt mal für 10.000 Dateien unter VS2003 C++ (Win32-Konsolenprojekt) erstellt und es läuft!

Wo erstellst du die Streams, auf dem Stack oder auf dem Heap?

Asmodeus
2004-06-18, 15:41:43
Original geschrieben von Gast
So.

Habe es jetzt mal für 10.000 Dateien unter VS2003 C++ (Win32-Konsolenprojekt) erstellt und es läuft!

Wo erstellst du die Streams, auf dem Stack oder auf dem Heap?

Die Streams werden bei mir im Heap erstellt, da ich sie dynamisch erstelle. Anders kann ich es auch nicht machen, da mir die Anzahl der benötigten Streams erst zur Lauftzeit bekannt ist.

Gruss, Carsten.

EgonOlsen
2004-06-18, 16:38:54
Das root-Verz. einer FAT16-Partition kann nur 512 Files aufnehmen, aber das wird ja hier wohl nicht das Problem sein, oder?

ScottManDeath
2004-06-18, 16:59:04
Vielleich kannst du es mit Memory Mapped Files probieren. Du bekommst von der Win32 API einen Zeiger zurück. Dieser entspricht dem Inhalt der Datei. Windows kümmert sich um das Paging & Co....