So überprüfen Sie, ob eine Datei in Qt in c ++ vorhanden ist

75

Wie überprüfe ich, ob eine Datei in einem bestimmten Pfad in Qt vorhanden ist oder nicht?

Mein aktueller Code ist unten:

QFile Fout("/Users/Hans/Desktop/result.txt");

if(!Fout.exists()) 
{       
  eh.handleError(8);
}  
else
{
  // ......
}

Wenn ich den Code ausführe, wird jedoch nicht die angegebene Fehlermeldung ausgegeben handleError, obwohl die im Pfad erwähnte Datei nicht vorhanden ist.

user1322915
quelle
1
Ich denke, @mozzbozz unten kann Ihre Antwort haben - vergessen Sie nicht, Punkte anzunehmen / zu geben :)
Rachael

Antworten:

101

(TL; DR unten)

Ich würde die QFileInfo-class ( docs ) verwenden - genau dafür ist es gemacht:

Die QFileInfo-Klasse bietet systemunabhängige Dateiinformationen.

QFileInfo bietet Informationen über den Namen und die Position (den Pfad) einer Datei im Dateisystem, ihre Zugriffsrechte und darüber, ob es sich um ein Verzeichnis oder einen symbolischen Link usw. handelt. Die Größe der Datei und die letzten Änderungs- / Lesezeiten sind ebenfalls verfügbar. QFileInfo kann auch verwendet werden, um Informationen zu einer Qt-Ressource abzurufen.

Dies ist der Quellcode, um zu überprüfen, ob eine Datei vorhanden ist:

#include <QFileInfo>

(Vergessen Sie nicht, die entsprechende #includeAnweisung hinzuzufügen)

bool fileExists(QString path) {
    QFileInfo check_file(path);
    // check if file exists and if yes: Is it really a file and no directory?
    if (check_file.exists() && check_file.isFile()) {
        return true;
    } else {
        return false;
    }
}

Beachten Sie auch: Möchten Sie nur überprüfen, ob der Pfad vorhanden ist ( exists()), oder möchten Sie auch sicherstellen, dass dies eine Datei und kein Verzeichnis ist ( isFile())?

Seien Sie vorsichtig : Die Dokumentation der Funktion exists()lautet:

Gibt true zurück, wenn die Datei vorhanden ist. Andernfalls wird false zurückgegeben.

Hinweis: Wenn die Datei ein Symlink ist, der auf eine nicht vorhandene Datei verweist, wird false zurückgegeben.

Das ist nicht genau. Es sollte sein:

Gibt true zurück, wenn der Pfad (dh Datei oder Verzeichnis) vorhanden ist. Andernfalls wird false zurückgegeben.


TL; DR

(mit einer kürzeren Version der obigen Funktion, die einige Codezeilen spart)

#include <QFileInfo>

bool fileExists(QString path) {
    QFileInfo check_file(path);
    // check if path exists and if yes: Is it really a file and no directory?
    return check_file.exists() && check_file.isFile();
}

TL; DR für Qt> = 5,2

(Verwenden existsals als, staticwas in Qt 5.2 eingeführt wurde; die Dokumente sagen, dass die statische Funktion schneller ist, obwohl ich nicht sicher bin, ob dies immer noch der Fall ist, wenn auch die isFile()Methode verwendet wird; zumindest ist dies dann ein Einzeiler)

#include <QFileInfo>

// check if path exists and if yes: Is it a file and no directory?
bool fileExists = QFileInfo::exists(path) && QFileInfo(path).isFile();
Mozzbozz
quelle
4
Nur ein Vorschlag, der Code in der Funktion bool fileExists(const QString &path)könnte weiter vereinfacht werden zu: return checkFile.exists() && checkFile.isFile(); @mozzbozz
Dreamer
@ Träumer Danke für deinen Kommentar. Natürlich haben Sie Recht, obwohl es auch Geschmackssache ist. Ich habe auch Ihre Version hinzugefügt (ich werde die längere Version hier belassen, da sie für Anfänger möglicherweise einfacher zu befolgen ist).
Mozzbozz
1
@kayleeFrye_onDeck Sei vorsichtig, deine Bearbeitung ist nicht wirklich korrekt. Es ist richtig, dass die Dokumente sagen, dass die statische Funktion schneller ist. Die Dokumente sind jedoch ziemlich ungenau, was die Funktion wirklich tut. Die Funktion exist (statisch oder nicht) prüft nur, ob der Pfad existiert, nicht, ob eine Datei vorhanden ist. Wenn es also ein Verzeichnis mit dem angegebenen Pfad gibt, wird Ihr Vorschlag ebenfalls zurückgegeben true! (habe es gerade auf meinem System mit Qt 5.10 getestet)
Mozzbozz
1
@kayleeFrye_onDeck Sicher (getestet mit Qt 5.6 unter Windows): gist.github.com/mozzbozz/2e83d7e3452a07fa817980403c42eade -> Ja, ich denke, das ist ein Missverständnis. Ich meinte, die existsFunktion ( staticoder nicht) gibt zurück, truewenn der angegebene Pfad ein Verzeichnis ist. Die Frage lautete jedoch "Wie überprüfe ich, ob eine Datei vorhanden ist" (und nicht das Verzeichnis ). Schauen Sie sich das verknüpfte Code-Snippet an. Ich hoffe, das erklärt, was ich meine.
Mozzbozz
1
Aber warte, es wird schlimmer haha: i.imgur.com/5Hds4kA.png "Datei" seufzen
kayleeFrye_onDeck
12

Sie können die QFileInfo::exists()Methode verwenden:

#include <QFileInfo>
if(QFileInfo("C:\\exampleFile.txt").exists()){
    //The file exists
}
else{
    //The file doesn't exist
}

Wenn Sie möchten, dass es truenur zurückgegeben wird, wenn die Datei vorhanden ist und falseder Pfad vorhanden ist, aber ein Ordner ist, können Sie ihn kombinieren mit QDir::exists():

#include <QFileInfo>
#include <QDir>
QString path = "C:\\exampleFile.txt";
if(QFileInfo(path).exists() && !QDir(path).exists()){
    //The file exists and is not a folder
}
else{
    //The file doesn't exist, either the path doesn't exist or is the path of a folder
}
Donald Duck
quelle
Seien Sie vorsichtig: Wenn Sie einen Pfad zu einem Verzeichnis angeben, wird auch Ihr Quellcode zurückgegeben true, obwohl es sich "nur" um eine Datei handelt. Das OP bat darum, nach einer Datei zu suchen, nicht nach einem Pfad.
Mozzbozz
1
@mozzbozz Wenn Sie möchten, dass es zurückgegeben wird, falsewenn der Pfad vorhanden ist, aber ein Ordner ist, können Sie dies tun QFileInfo(path).exists() && !QDir(path).exists(). Ich habe meine Antwort bearbeitet, um das hinzuzufügen.
Donald Duck
8

Der von Ihnen gepostete Code ist korrekt. Wahrscheinlich stimmt etwas anderes nicht.

Versuchen Sie Folgendes:

qDebug() << "Function is being called.";

innerhalb Ihrer handleError-Funktion. Wenn die obige Meldung gedruckt wird, wissen Sie, dass etwas anderes das Problem ist.

Anthony
quelle
3

So überprüfe ich, ob die Datenbank existiert:

#include <QtSql>
#include <QDebug>
#include <QSqlDatabase>
#include <QSqlError>
#include <QFileInfo>

QString db_path = "/home/serge/Projects/sqlite/users_admin.db";

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(db_path);

if (QFileInfo::exists(db_path))
{
    bool ok = db.open();
    if(ok)
    {
        qDebug() << "Connected to the Database !";
        db.close();
    }
}
else
{
    qDebug() << "Database doesn't exists !";
}

Mit SQLitees schwierig ist , zu überprüfen , ob die Datenbank vorhanden ist , weil es automatisch eine neue Datenbank erstellt , wenn sie noch nicht existiert.

Essetee
quelle
2
Wie hängt das mit der Frage zusammen?
VK
1

Ich würde alles von Qt überspringen und einfach den alten Standard verwenden access:

if (0==access("/Users/Hans/Desktop/result.txt", 0))
    // it exists
else
    // it doesn't exist
Jerry Sarg
quelle
@ Styne666: Jeder Compiler, von dem ich weiß, dass er Windows unterstützt access- sicherlich MS und die gcc-Ports. Intel verwendet die MS-Bibliothek, die dies unterstützt, und Comeau verwendet die Bibliothek des Back-End-Compilers.
Jerry Coffin
Vielen Dank, dass Sie mich dazu gebracht haben, meine Nachforschungen anzustellen. Ich akzeptiere, dass dies anscheinend funktioniert, aber angesichts der Kommentare zu dieser Antwort denke ich immer noch, dass es eine bessere Lösung ist, sich an die Optionen von Qt zu halten (wenn Sie ein Qt-Projekt haben).
Samuel Harmer
2
@ Styne666: Ich bin mir nicht sicher, ob Qt irgendetwas bietet, um das Problem für setuid / setgid-Programme zu beheben, was anscheinend das einzige ist, das zählt. Sie diskutierten über die Bedeutung von "plattformübergreifend" und welche Standards zu beachten sind, aber wenn wir uns nur um die von Qt unterstützten Plattformen kümmern, sind dies meistens strittige Punkte.
Jerry Coffin