I've been trying to read .xml file using QFile. But qt creator can't even find it, but file exists inside project (also I tried to read it from another directory, not project's, it doesn't work, too). Debuger says file not accessible.
Here's my code:
QFile file("../info.xml");
if (file.exists())
if (file.open(QFile::ReadOnly | QFile::Text))
qDebug(qPrintable("File exist"));
This is not a complete answer, but rather a list of what may have gone wrong.
Check the file path :
QFileInfo inf (file);
qDebug() << inf.QFileInfo::path();
Ensure that the file is in the right directory, i.e. in the same you have your .exe (build-ProjectName-...). You can check this by using QDir::currentPath()
Check which if causes the problem : is it the first one which checks file existence or the second one that cannot open it ?
I am not sure it is a good idea to use the QFile::Text for .xml files.
In the end, I would do something like this :
QFile file("../info.xml");
QFileInfo inf (file);
qDebug() << "File path : "<< inf.QFileInfo::path() << Qt::endl;
qDebug() << "Current path : " << QDir::currentPath() << Qt::endl;
qDebug() << "Current path (expected) : " << QDir::currentPath() + "/info.xml" << Qt::endl;
if (file.exists()){
qDebug() << "exists" << Qt::endl;
if (file.open(QFile::ReadOnly)){qDebug() << "opened";}
}
Related
Would really appreciate your help. I'm new to Qt and C++.
I managed to get this working previously, but for some reason am no longer able to do so. I haven't touched anything to do with the writing of files, but all functions pertaining to file writing no longer seem to function. Here's an example of one of the simpler write functions:
#include <QStringList>
#include <QDir>
#include <QFile>
#include <QString>
#include <QTextStream>
void HandleCSV::writeToPIDCSV(UserAccount newUser)
{
// Storing in userPID db
QString filePath = returnCSVFilePath("dbPID");
qDebug() << "File path passsed to writeToPIDCSV is " << filePath;
// Open CSV filepath retrieved from associated dbName
QFile file(filePath);
if (!file.open(QIODevice::ReadWrite | QIODevice::Append))
{
qDebug() << file.isOpen() << "error " << file.errorString();
qDebug() << "File exists? " << file.exists();
qDebug() << "Error message: " << file.error();
qDebug() << "Permissions err: " << file.PermissionsError;
qDebug() << "Read error: " << file.ReadError;
qDebug() << "Permissions before: " << file.permissions();
// I tried setting permissions in case that was the issue, but there was no change
file.setPermissions(QFile::WriteOther);
qDebug() << "Permissions after: " << file.permissions();
}
// if (file.open(QIODevice::ReadWrite | QIODevice::Append))
else
{
qDebug() << "Is the file open?" << file.isOpen();
// Streaming info back into db
QTextStream stream(&file);
stream << newUser.getUID() << "," << newUser.getEmail() << "," << newUser.getPassword() << "\n";
}
file.close();
}
This gets me the following output when run:
File path passsed to writeToPIDCSV is ":/database/dummyPID.csv"
false error "Unknown error"
File exists? true
Error message: 5
Permissions err: 13
Read error: 1
Permissions before: QFlags(0x4|0x40|0x400|0x4000)
Permissions after: QFlags(0x4|0x40|0x400|0x4000)
The file clearly exists and is recognised when run, but for some reason file.isOpen() is false, and the permissions show that the user only has read (not write) permissions that are unaffected by permission settings.
Would someone have a clue as to why this is happening?
Many thanks in advance
Update
Thanks #chehrlic and #drescherjm - I didn't realise that I can only read but not write to my resource file!
Using QStandardPaths allows me to write to my AppDataLocation. I've included the code below for others who might encounter similar issues, adapted from https://stackoverflow.com/a/32535544/9312019
#include <QStringList>
#include <QDir>
#include <QFile>
#include <QString>
#include <QTextStream>
#include <QStandardPaths>
void HandleCSV::writeToPIDCSV(UserAccount newUser)
{
auto path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
if (path.isEmpty()) qFatal("Cannot determine settings storage location");
QDir d{path};
QString filepath = returnCSVFilePath("dbPID");
if (d.mkpath(d.absolutePath()) && QDir::setCurrent(d.absolutePath()))
{
qDebug() << "settings in" << QDir::currentPath();
QFile f{filepath};
if (f.open(QIODevice::ReadWrite | QIODevice::Append))
{
QTextStream stream(&f);
stream << newUser.getUserFirstName() << ","
<< newUser.getUserIDNumber() << "\n";
}
}
}
Am now testing to make this work with my Read functions.
If there's any way to be able to write to the Qt program's folder (or build folder), I'd really appreciate it!
You can not write to a Qt resource. If you want to update/write to a file you should put the file into a writeable filesystem. To e.g. place it in the appdata folder you can use QStandardPaths::writeableLocation(QStandardPaths::ApplicationsLocation)
I have this file which is located in my C drive, I know it exists. When I access it with QFile.exists() it returns false, however it still opens the file and writes to it, I just cant read it. I've been working on this for a while and cannot find a solution, any suggestions are appreciated.
QFile tmpfile("C:/file.txt");
QString tmpcontent;
if(!QFile::exists("C:/file.txt"))
qDebug() << "File not found"; // This is outputted
if (tmpfile.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
QTextStream stream(&tmpfile);
stream << "test"; //this is written
tmpcontent = tmpfile.readAll(); // this returns nothing
}
If file is not exist it will be created by open because you do it in write mode.
readAll function return all remaining data from device, since you just write something you are currently at the end of a file, and there is no data, try to seek( 0 ) to return to the beginnig of a file and then use readAll.
qDebug() << "File exists: " << QFile::exists("text.txt");
QFile test( "text.txt" );
if ( test.open( QIODevice::ReadWrite | QIODevice::Truncate ) ){
QTextStream str( &test );
str << "Test string";
qDebug() << str.readAll();
str.seek( 0 );
qDebug() << str.readAll();
test.close();
}else{
qDebug() << "Fail to open file";
}
As I can see from your code you need that file as a temporary, in such case I suggest to use QTemporaryFile, it will be created in temp directory (I belive there will be no problem with permissions), with unique name and will be auto deleted in object dtor.
I'm trying to read a text file and display the contents in a QPlainTextEdit. Please can you point out what I'm doing wrong:
QFile jsonFile("data.json");
if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "Failed to open file";
qDebug() << jsonFile.errorString();
return;
}
else
{
qDebug() << "File opened";
} //It returns that the file opened successfully
qDebug() << "File Exists?: " << jsonFile.exists(); //Yep, it exists.
QTextStream outStream(&jsonFile);
QString textString = outStream.readAll();
qDebug() << "Text string: " << textString; //textString is empty! ""
ui->fileToPost->setPlainText(textString); //fileToPost is the QPlainTextEdit
jsonFile.close();
If I do something like
QString textString = "The cat sat on the mat";
it displays fine. The problem is that nothing is being read from the stream (or maybe the file).
Try to check file's absolute path, probably it is not where, you expect it: qDebug()<<QFileInfo("data.json").absoluteFilePath();
I have my slot being called whenever someone clicks the link and I know the file is there because I can retrieve the file name and the amount of bytes the file is just not sure how to s ave it after I call the QFileDialog::getSaveFileName? I know that gives me the name of the file if the user decides to change it but how do I get the location they decide to save it in and then write it to that location.
NB: The file they will download is a word doc if that makes any difference?
void MainWindow::unsupportedContent(QNetworkReply *reply) {
qDebug() << "Left click - download!";
qDebug() << "Bytes to download: " << reply->bytesAvailable();
QString str = reply->rawHeader("Content-Disposition");
QString end = str.mid(21);
end.chop(1);
qDebug() << "string: " << end;
qDebug() << "File name: " << reply->rawHeader("Content-Disposition");
qDebug() << "File type: " << reply->rawHeader("Content-Type");
QString defaultFileName = QFileInfo(end).fileName();
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), defaultFileName);
if (fileName.isEmpty()) return;
QFile *file = new QFile(fileName);
file->open(fileName);
file->write(reply->read(reply->bytesAvailable()));
file->close();
}
today i explained it on another post so i will link that post here : Post
i can tell you that you have only to implement a slot that write into the file you created. and call it when readyRead() signal is emitted.
I'm using Qt to develop my C++ application using QML as well.
Here's my code
QFile inputFile("data.txt");
//QFile inputFile("/:data.txt");
qDebug() << "Hello:";
if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "Wasn't ready:";
}
else{
qDebug() << "Txt file ready:";
QTextStream in(&inputFile);
while ( !in.atEnd() )
{
QString line = in.readLine();
qDebug() << "message: " << line;
}
}
I was wondering why it doesn't work. The console always prints "Wasn't ready".
Please help.
In the error handling block where you do qDebug() << "Wasn't ready:"; you should call inputFile.error() and print out the returned value to get more details of what went wrong.
It might also be an idea to start the program with printing out the current directory, to make sure that the file is searched for in the correct location.