Verzeichnisse

Informationen über Verzeichnisse und deren Inhalt können über die Klasse QDir abgefragt werden. Um ein QDir-Objekt zu einem bestimmten Verzeichnis zu erstellen, kann einfach der Pfad an den Konstruktor übergeben werden. Weiters können auch Verzeichnisse und ganze Pfade angelegt bzw. gelöscht werden.

Informationen lesen und schreiben

Verzeichnis auf Existenz prüfen

Über die Methode exists() kann abgefragt werden, ob das durch das QDir repräsentierte Verzeichnis tatsächlich existiert. Das folgende Programm prüft, ob ein per Kommandozeilenparameter übergebenes Verzeichnis existiert:

#include <QDir>
#include <iostream>
 
int main( int argc, char *argv[] )
{
  if( argc < 2 )
  {
    std::cout << "Programm benoetigt Verzeichnisnamen als Parameter." << std::endl;
    return 1;
  }
  QDir dir( argv[1] );
  std::cout << dir.exists() << std::endl;
  return 0;
}

Systeminformationen

QDir bietet auch eine Reihe statischer Methoden um Systeminformationen abzufragen und zu ändern. Hier eine Übersicht der wichtigsten Methoden:

Aktuelles Verzeichnis

QDir current()

Gibt ein QDir-Objekt für das aktuelle Anwendungsverzeichnis zurück.

QString currentPath()

Gibt den Pfad des aktuellen Anwendungsverzeichnisses zurück.

bool setCurrent( const QString& path )

path: Neues Anwendungsverzeichnis
Return value: Wahr bei Erfolg, ansonsten falsch
Setzt das Anwendungsverzeichnis auf path.

Benutzerverzeichnis

QDir home()

Gibt ein QDir-Objekt für das Benutzerverzeichnis zurück.

QString homePath()

Gibt den Pfad des Benutzerverzeichnisses zurück.

Trennzeichen

QChar separator()

Gibt das systemabhängige Trennzeichen für Pfade zurück. Unter Linux/Unix ist das '/', Windows hingegen verwendet '\'.

Verzeichnis für temporäre Dateien

QDir temp()

Gibt ein QDir-Objekt für das temporäre Verzeichnis zurück.

QString tempPath()

Gibt den Pfad des temporären Verzeichnisses zurück.

Verzeichnis-Baum

Die folgenden Programme sollen einen Verzeichnis-Baum folgender Ordnerstruktur im Verzeichnis /home/user/ ausgeben:

  • Ordner: basedir
    • Unterordner: A
      • Unterordner: D
        • Datei: D1
      • Unterordner: E
      • Datei: A1
      • Datei: A2
      • Datei: A3
    • Unterordner: B
      • Datei: B1
      • Datei: B2
    • Unterordner: C
      • Unterordner: F
        • Datei: F1
        • Datei: F2

Iterator

Qt bietet einen fertigen Iterator der alle enthaltenen Dateien eines Verzeichnisses und dessen Unterverzeichnissen durchläuft.

// main.cpp
#include <QDirIterator>
#include <iostream>
 
using namespace std;
 
int main( int argc, char *argv[] )
{
  if( argc != 2 )     // Pfad zum Ordner muss als Kommandozeilenparameter übergeben werden
  {
    cout << "Programm benoetigt genau 1 Parameter." << endl;
    return 1;
  }
 
  QDirIterator it( argv[1], QDirIterator::Subdirectories ); // Iterator für Verzeichnis erstellen
  cout << "base directory: " << it.path().toStdString() << endl; // Grundverzeichnis ausgeben
  it.next();                                                // nächstes Verzeichnis
 
  do
  {
    // auf gültiges Verzeichnis prüfen
    if( it.fileInfo().isDir() && it.fileName() != "." && it.fileName() != "..")
      cout << "\tsubdirectory: " << it.fileName().toStdString() << endl;
    else if( it.fileInfo().isFile() )              // prüfen ob es eine Datei ist
      cout << "\t\tfile: " << it.fileName().toStdString () << endl;
    it.next();                 // nächste Datei bzw. Ordner
  } while( it.hasNext() );     // Schleife läuft solange Dateien oder Ordner im Verzeichnis sind
 
  return 0;
}

Ausgabe:

base directory: /home/user/basedir/
	subdirectory: C
	subdirectory: F
		file: F2
		file: F1
	subdirectory: A
	subdirectory: D
		file: D1
		file: A2
		file: A3
		file: A1
	subdirectory: E
	subdirectory: B
		file: B1
		file: B2

Rekursive Lösung

Oft ist es umständlich mit dem Iterator zu arbeiten. Wenn die Verzeichnisstruktur wichtig ist kann man rekursiv alle Unterordner und Dateien in einer Baumstruktur speichern.

// main.cpp
#include "Directory.h"
 
int main( int argc, char *argv[] )
{
  if( argc != 2 )        // Pfad zum Ordner muss als Kommandozeilenparameter übergeben werden
  {
    cout << "Programm benoetigt einen Pfad als Parameter." << endl;
    return 1;
  }
 
  Directory dir( argv[1] );
  dir.print();
 
  return 0;
}
// Directory.h
#ifndef DIRECTORY_H
#define DIRECTORY_H
 
#include <QFileInfo>
#include <QDir>
#include <QList>
#include <iostream>
 
using namespace std;
 
// Klasse für einen Ordner; enthält Listen mit Unterordner und Dateien
class Directory
{
 
  public:
    Directory( const QString& path );     // Konstruktor; Pfad zum Verzeichnis wird übergeben
    ~Directory ();
    void print( int indention = 0 );      // gibt den Verzeichnis-Baum aus, Einzug wird übergeben
 
  private:
    QString m_path;                       // Pfad zum Verzeichnis
    QList<Directory *> m_subdirs;         // Liste mit Unterordnern
    QList<QFileInfo> m_files;             // Liste mit Dateien im Verzeichnis
    int m_indention;                      // zusätzlicher Einzug je Einrückungsebene
    void printIndention( int indention ); // Ausgabe des Einzugs
 
};
 
#endif
// Directory.cpp
#include "Directory.h"
 
Directory::Directory( const QString& path ) : m_path( path )  // Pfad speichern
{
  m_indention = 4;          // Standard-Einzug ist 4 Leerzeichen
  QFileInfoList filelist = QDir( ( m_path ) ).entryInfoList();  // Liste mit Ordnerinhalt abrufen
 
  for( int i = 0; i < filelist.size(); i++ )
  {
    // prüfen ob Eintrag ein gültiges Verzeichnis ist
    if( filelist[i].isDir() && filelist[i].fileName() != "." && filelist[i].fileName() != ".." )
      m_subdirs.push_back( new Directory( filelist[i].filePath() ) );  // Eintrag als Unterverzeichnis abspeichern
    else if( filelist[i].isFile() )       // prüfen ob Eintrag eine Datei ist
      m_files.push_back( filelist[i] );   // Info zur Datei in Liste abspeichern
  }
}
 
 
Directory::~Directory()
{
  while( m_subdirs.size() > 0 )       // Speicher für Unterverzeichnisse löschen
    delete m_subdirs.takeFirst();
}
 
 
void Directory::print( int indention )
{
  printIndention( indention );                // Einzug ausgeben
  cout << m_path.toStdString() << endl;       // Namen des Verzeichnisses ausgeben
  indention += m_indention;                   // Einzug für Inhalt des Ordners erhöhen
 
  for( int i = 0; i < m_files.size(); i++ )   // Dateien ausgeben
  {
    printIndention( indention );
    cout << m_files[i].fileName().toStdString() << endl;
  }
 
  for( int i = 0; i < m_subdirs.size(); i++ )
    m_subdirs[i]->print( indention );         // Aufruf dieser Funktion für alle Unterordner
}
 
 
void Directory::printIndention( int indention )  // gibt die übergebene Anzahl an Leerzeichen aus
{
  for( int i = 0; i < indention; i++ )
    cout << ' ';
}

Ausgabe:

/home/user/basedir/
    /home/user/basedir/A
        A1
        A2
        A3
        /home/user/basedir/A/D
            D1
        /home/user/basedir/A/E
    /home/user/basedir/B
        B1
        B2
    /home/user/basedir/C
        /home/user/basedir/C/F
            F1
            F2

Verzeichnisse erstellen und löschen

FIXME mkdir, rmdir, mkpath, rmpath