Umgehung der I/O-Addressierungsgrenzen auf 32-bit System

Traveller

Mitglied
Hallo Leute,

ich möchte in C++ mit einem ifstream Daten aus einer sehr großen Ascii-Datei (3,17 GB) auslesen. Die Datei enthält unmengen Integer-Werte, nicht binär codiert, sondern als Ascii-Zeichen, also "menschenlesbar".
Bei einem Testlauf meines Codes habe ich festgestellt, dass bei ca. 2 GB Schluss ist mit Stream lesen, logischerweise beim höchsten Wert, der mit 32 bit adressierbar ist. Nun muss es aber möglich sein, auch darüber hinaus zu adressieren, ein 32-bit XP oder Linux kommen schließlich auch mit so einer Datei klar.
Ein Blick in die Boost-Lib hat mich leider nicht weiter gebracht. Es ist auch gar nicht so leicht, Google(TM) beizubringen, was ich eigentlich suche :rolleyes:. Muss ich einen System-Fork mit dem Präprozessor machen und die System-APIs nutzen? Das wäre für so ein Freizeitprojekt nicht allzuviel Aufwand, aber geht das nicht auch plattformunabhängig?


Mein Code ist bei der Frage eigentlich irrelevant, ich poste aber mal die relevanten Teile.

Code:
char *path = "C:\\foo.asc";
std::ifstream ifsFoo(path, std::ios::in);
if (!ifsFoo)
	return -1;

int bufSize = 1024;
char buffer[bufSize];

while (ifsFoo.good())
{
	std::cout << "Streamposition: " << ifsFoo.tellg() << std::endl;
	ifsFoo.get(buffer, bufSize);
}

ifsFoo.close();

Schönes Wochenende wünsch ich euch.
Gruß, Traveller


Nachtrag: Falls sich jemand wundert, es handelt sich um SRTM-Daten.
http://de.wikipedia.org/wiki/SRTM-Daten
 
Zuletzt bearbeitet:
Hi.
Hallo Leute,

ich möchte in C++ mit einem ifstream Daten aus einer sehr großen Ascii-Datei (3,17 GB) auslesen. Die Datei enthält unmengen Integer-Werte, nicht binär codiert, sondern als Ascii-Zeichen, also "menschenlesbar".
Bei einem Testlauf meines Codes habe ich festgestellt, dass bei ca. 2 GB Schluss ist mit Stream lesen, logischerweise beim höchsten Wert, der mit 32 bit adressierbar ist. Nun muss es aber möglich sein, auch darüber hinaus zu adressieren, ein 32-bit XP oder Linux kommen schließlich auch mit so einer Datei klar.
Lesen ist ja nicht das Problem, lediglich die Adressierung. Mußt du denn die Stream-Position lesen / setzen können?
Ein Blick in die Boost-Lib hat mich leider nicht weiter gebracht.
Boost.Iostreams haben LFS (Large File Support). Es sollte also einfach funktionieren.

\edit: Ganz so einfach ist es wohl nicht. Schau dir mal den LFS Test von Boost.Iostreams an: http://svn.boost.org/svn/boost/trunk/libs/iostreams/test/large_file_test.cpp
Code:
char *path = "C:\\foo.asc";
std::ifstream ifsFoo(path, std::ios::in);
if (!ifsFoo)
	return -1;

int bufSize = 1024;
char buffer[bufSize];

while (ifsFoo.good())
{
	std::cout << "Streamposition: " << ifsFoo.tellg() << std::endl;
	ifsFoo.get(buffer, bufSize);
}

ifsFoo.close();
Dein Code ist problematisch. Verwende niemals die good(), bad(), fail(), eof() Methoden auf diese Weise sondern frage den Erfolg von Lese-/Schreiboperationen direkt ab:
C++:
do {
	std::cout << "Streamposition: " << ifsFoo.tellg() << std::endl;
} while (ifsFoo.get(buffer, bufSize));
Gruß
 
Zuletzt bearbeitet:
Hallo Traveller,

du musst ja nicht absolut adressieren, sondern kannst auch relativ zur aktuellen Streampositionen adressieren und dich damit bis zur gewünschten Position durchhangeln:
C++:
    std::ifstream ifs( "my_big_file.xyz" );
    
    const unsigned int GByte = 0x40000000;
    
    if( ifs.is_open() )
    {
        for( int i = 0; i < 10; ++i )
        {
            ifs.seekg(GByte, std::ios_base::cur);
            
            char cRead;
            ifs.read (&cRead, 1);
            
            std::cout << "Read byte at position "
                      << i
                      << " GByte: "
                      << cRead
                      << std::endl;
        }
        
        ifs.close();
    }
Gruß
MCoder
 
Danke, Thema erledigt.
Ja mit boost ist das doch nicht so einfach, das durchhangeln erscheint mir pragmatischer, funktioniert auch bestens.
MCoder, deepthroat, danke für eure Hilfe. Man lernt doch immer wieder was neues.
 
Zurück