Як перевірити, чи існує файл у Qt на c ++


79

Як мені перевірити, чи існує файл у заданому шляху чи ні в Qt?

Мій поточний код знаходиться нижче:

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

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

Але коли я запускаю код, він не видає повідомлення про помилку, вказане в, handleErrorхоча файл, про який я згадав у шляху, не існує.


1
Я думаю, що @mozzbozz нижче може отримати вашу відповідь - не забудьте прийняти / дати бали :)
Рейчел

Відповіді:


103

(TL; DR внизу)

Я б використав QFileInfo-class ( docs ) - саме для цього він створений:

Клас QFileInfo забезпечує незалежну від системи інформацію про файли.

QFileInfo надає інформацію про ім'я та позицію файлу (шлях) у файловій системі, його права доступу, а також про те, чи це каталог або символічне посилання тощо. Також доступні розмір файлу та час останньої зміни / читання. QFileInfo також може використовуватися для отримання інформації про ресурс Qt.

Це вихідний код, щоб перевірити, чи існує файл:

#include <QFileInfo>

(не забудьте додати відповідну #includeзаяву)

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;
    }
}

Також враховуйте: Ви хочете лише перевірити, чи існує шлях ( exists()), або Ви також хочете переконатися, що це файл, а не каталог ( isFile())?

Будьте обережні : У документації до функції exists()зазначено:

Повертає true, якщо файл існує; інакше повертає false.

Примітка: Якщо файл є символічним посиланням, яке вказує на неіснуючий файл, повертається значення false.

Це не точно. Вона повинна бути:

Повертає true, якщо шлях (тобто файл чи каталог) існує; інакше повертає false.


TL; DR

(із коротшою версією функції вище, зберігаючи кілька рядків коду)

#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 для Qt> = 5,2

(використовуючи existsяк a, staticякий було введено в Qt 5.2; у документах сказано, що статична функція швидша, хоча я не впевнений, що це все ще має місце при використанні isFile()методу; принаймні, це однокласний вкладиш)

#include <QFileInfo>

// check if path exists and if yes: Is it a file and no directory?
bool fileExists = QFileInfo::exists(path) && QFileInfo(path).isFile();

4
Тільки пропозиція, код у функції bool fileExists(const QString &path)можна ще спростити: return checkFile.exists() && checkFile.isFile(); @mozzbozz
Dreamer

@Dreamer Дякую за ваш коментар. Звичайно, ти маєш рацію, хоча це теж питання смаку. Я також додав вашу версію (довшу версію я залишу тут, оскільки для початківців може бути простіше).
mozzbozz

1
@kayleeFrye_onDeck Будьте обережні, ваше редагування насправді неправильне. Правильно, що в документах сказано, що статична функція швидша. Однак документи досить неточні щодо того, що функція насправді робить. Функція існує (статична чи ні) лише перевіряє, чи існує шлях, а не чи є файл. Отже, якщо є каталог із заданим шляхом, ваша пропозиція також повернеться true! (щойно протестував на моїй системі з Qt 5.10)
mozzbozz

1
@kayleeFrye_onDeck Звичайно (протестовано з Qt 5.6 під Windows): gist.github.com/mozzbozz/2e83d7e3452a07fa817980403c42eade -> Так, я думаю, це непорозуміння. Я мав на увазі, що existsфункція ( staticчи ні) повертається, trueякщо заданий шлях є каталогом. Однак питання було "Як мені перевірити, чи існує файл " (а не каталог ). Погляньте на зв’язаний фрагмент коду, я сподіваюся, це пояснює, що я маю на увазі.
mozzbozz

1
Але почекайте, стає гірше ха-ха: i.imgur.com/5Hds4kA.png "файл" зітхання
kayleeFrye_onDeck

13

Ви можете використовувати QFileInfo::exists()метод:

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

Якщо ви хочете, щоб він повертався, trueлише якщо файл існує і falseякщо шлях існує, але є папкою, ви можете поєднати його з 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
}

Будьте обережні: якщо ви вкажете шлях до каталогу, ваш вихідний код також повернеться true, навіть якщо це "лише" файл. ОП попросив перевірити файл, а не шлях.
mozzbozz

1
@mozzbozz Якщо ви хочете, щоб він повернувся, falseякщо шлях існує, але є папкою, ви можете це зробити QFileInfo(path).exists() && !QDir(path).exists(). Я відредагував свою відповідь, щоб додати це.
Дональд Дак,

8

Код, який ви опублікували, правильний. Швидше за все, щось інше не так.

Спробуйте поставити це:

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

всередині вашої функції handleError. Якщо вищезгадане повідомлення друкується, ви знаєте, що проблема полягає в іншому.


3

Ось як я перевіряю, чи існує база даних:

#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 !";
}

З SQLiteцим важко перевірити, чи існує база даних, оскільки вона автоматично створює нову базу даних, якщо вона не існує.


3
як це стосується питання?
ВК

1

Я б взагалі пропустив будь-що з Qt і просто використав старий стандарт access:

if (0==access("/Users/Hans/Desktop/result.txt", 0))
    // it exists
else
    // it doesn't exist

@ Styne666: Кожен компілятор, про який я знаю в Windows, підтримує access- безумовно, MS та порти gcc. Intel використовує бібліотеку MS, яка її підтримує, а Comeau використовує бібліотеку внутрішнього компілятора.
Джеррі Коффін

Дякуємо, що змусили мене зробити своє дослідження. Я погоджуюсь, що це може спрацювати, але, беручи до уваги коментарі до цієї відповіді, я все одно вважаю, що дотримання варіантів Qt (якщо у вас проект Qt) є кращим рішенням.
Семюель Хармер,

2
@ Styne666: Я взагалі не впевнений, що Qt пропонує щось для вирішення проблеми програм setuid / setgid, що, схоже, стосується єдиної, що має значення. Вони сперечались щодо значення "крос-платформа" та про те, які стандарти слід дбати, але якщо ми дбаємо лише про платформи, що підтримуються Qt, це в основному спірне питання.
Джеррі Коффін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.