std::ifstream und Verzeichnisse?



  • Hi,

    ich hab heute etwas komisches festgestellt. Bei mir(Ubuntu Lucid Lynx) funktioniert das öffnen von Verzeichnissen mit std::ifstream . Mit std::ofstream schlägt das Ganze jedoch fehl.
    Folgendes Beispiel wird in diesem Ordner ausgeführt:

    [~/test/] //Ordner
        - main.cpp
        - main.o
        - main
        - [blubb] //Ordner
    

    , und liefert diese Ausgabe:

    std::ifstream: ./blubb ist offen.
    std::ofstream: ./blubb ist zu.
    

    Das ist main.cpp:

    #include <iostream>
    #include <fstream>
    #include <string>
    
    int main( )
    {
    	std::string ordner( "./blubb" );
    
    	std::ifstream iFile;
    	iFile.open( ordner.c_str() );
    	std::cout << "std::ifstream: " << ordner << " ist ";
    	if( iFile.is_open() ) std::cout << "offen." << std::endl;
    	else                std::cout << "zu." << std::endl;
    
    	std::ofstream oFile;
    	oFile.open( ordner.c_str() );
    	std::cout << "std::ofstream: " << ordner << " ist ";
    	if( oFile.is_open() ) std::cout << "offen." << std::endl;
    	else                std::cout << "zu." << std::endl;
    
    	return 0;
    }
    

    Wieso geht das? Und, wie kann ich das Unterbinden?
    Ich hoffe, ich muss nicht erst mit opendir und d_type herumspielen, oder?

    MfG. Christoph Ludwig



  • Vermutlich musst du das Handle mit iFile.close(); erst schließen.



  • ok, nein, falsch verstanden.
    Mit (i/o)fstream will ich nur Dateien, aber KEINE Verzeichnisse öffnen.
    std::ofstream zeigt also das gewünschte Verhalten. std::ifstream aber nicht. Wie kann ich trotzdem feststellen( Vielleicht gibts da was ohne opendir und d_type ), ob ich mit std::ifstream jetzt eine Datei oder ein Verzeichnis offen habe?

    Das Problem hab ich festgestellt, als ich den gesamten Inhalt einer Datei auslesen wollte.
    Sowas artet in einer Endlos-Schleife aus:

    std::string content;
    std::string buffer;
    std::ifstream iFile( "./blubb" ); //blubb ist ein Verzeichnis
    while( !iFile.eof() ) //Endlosschleife
    {
    	getline( iFile, buffer );
    	content += buffer;
    }
    


  • Hallo Christoph!

    Wenn ich Dich recht verstehe, suchst Du einen Test, der auskommt, ohne plattformspezifische Dateisachen einzubinden?
    Vielleicht kannste testen, ob ifstream("./blubb/.") öffnet und wenn ja, war's ein Verzeichnis. (Wobei selbst dieser Test dann wieder nur so lange gilt, bis jemand ein Dateisystem reinwirft, das die Datei ./blubb und das Verzeichnis ./blubb/. koexistieren läßt. Vorm reiserfs hätte ich da ein wenig Angst.)



  • Hi,

    ich habs jetzt also mit opendir gemacht. Da muss ich nur noch mit dem Präprozessor herumspielen, damit es etwas portabler(Linux/Windoof/Apfeltasche) ist. Noch etwas zu verbessern, oder sollte ich gleich ne Wrapper-Klasse für std::fstream machen?

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <dirent.h>
    
    bool isDir( std::string str )
    {
    	DIR *directoryPointer = 0;
    	directoryPointer = opendir( str.c_str() );
    	if( directoryPointer != 0 )
    	{
    		closedir( directoryPointer );
    		return true;
    	}
    	return false;
    }
    
    bool openFile( std::string path, std::fstream &file, std::ios_base::openmode mode )
    {
    	if( isDir( path ) ) return false;
    	if( file ) file.close();
    	file.open( path.c_str(), mode );
    	return file.is_open();
    }
    
    int main( )
    {
    	std::string dirName( "./blubb" );
    	std::string fileName( "./test.txt" );
    	std::fstream file;
    	std::cout << "File \"" << dirName << "\" is " << openFile( dirName, file, std::ios::in ) << std::endl;
    	std::cout << "File \"" << fileName << "\" is " << openFile( fileName, file, std::ios::in ) << std::endl;
    	return 0;
    }
    

    "./blubb" ist ein Ordner, "./test.txt" eine Datei. Ausgabe ist wie gewünscht so, dass die Datei, aber nicht der Ordner geöffnet wird:

    File "./blubb" is 0
    File "./test.txt" is 1
    

    MfG. Christoph Ludwig



  • Unter Linux sind Ordner auch Dateien. Was du sagst ergibt also so keinen Sinn: "Ich will nur Dateien, aber keine Verzeichnisse öffnen."



  • Janjan schrieb:

    Unter Linux sind Ordner auch Dateien. Was du sagst ergibt also so keinen Sinn: "Ich will nur Dateien, aber keine Verzeichnisse öffnen."

    Für den Benutzer ergibt es aber Sinn.



  • Er ist aber Entwickler und kein Benutzer.



  • @Ich weis, Janjan.
    Nur wenn ich z.B. einen Filebrowser mache und der Benutzer einen Ornder bei "Wählen Sie eine Datei" angibt. Was dann?
    Zudem ist es mit egal, was das System macht. Ein Pfad besteht aus Verzeichnissen und am Ende vielleicht aus einer Datei( "[Dir]/[Dir]/[File]" ) und nicht aus vielen Dateien.
    Wenn ich einen String in eine Datei schreibe, schreibe ich auch nicht in ein Verzeichnis.
    Insofern unterscheide ich da, als Entwickler UND Benutzer.


Anmelden zum Antworten