Write file to Linux Application data directory - c++

I need to write files to the Application Data directory of the application that I'm designing. Im developing under Ubuntu using Qt. The following snippet shows my write function:
FileOperations::Error FileOperations::saveUsage(SensorIdentification sensorID, QList<UsageListModel::Usage> &usageList)
{
QString fileName(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
fileName.append("/");
fileName.append("testnaam");
fileName.append(FILE_EXTENSION);
this->sensorID = sensorID;
QFile file(fileName);
if(!file.open(QIODevice::WriteOnly))
{
return Error::FileNotOpen;
}
QDataStream out(&file);
out << sensorID;
for(int i = 0; i < usageList.size(); i++)
out << usageList.at(i).date << usageList.at(i).totalSteps << usageList.at(i).wearTime;
if(file.size())
{
file.close();
return Error::NoError;
}
else
{
file.close();
return Error::WritingToFileFailed;
}
}
The fileName after the appends is: "/home/jan/.local/share/Foo/Bar With Spaces/testnaam.liv"
For some reason I cant write a file in that directory. It does work correctly when i write to the users documents folder. Why cant i write to the appdata folder?

Related

How to check if a file is write protected in QT?

I need to check if a file is writable, to display a warning message when users try to open a file that is not writable.
I found on the QT forums the following examples to check if a file is writable:
const QFileInfo info(fileName);
if (info.permission(QFile::WriteOwner | QFile::WriteGroup | QFile::WriteUser)) {
qDebug() << "File is writable";
} else {
qDebug() << "Read Only file";
}
// Or even simpler:
if (info.isWritable()) {
qDebug() << "File is writable";
} else {
qDebug() << "Read Only file";
}
But unfortunately the above examples only works if a file has a read-only attribute, like this (this file is simple txt and I marked it as read-only):
I found in QT forums that I should look at the file permissions first. So, as you can see my file is not a read-only file (this is the permission of the real file I'm working).
If I go to the security section of the file's properties, I realize that the file only has permissions to read and execute, and of course not to write.
I tried to get the file permissions with the following code, but it doesn't seem to work.
QFileDevice::Permissions p = QFile(fileName).permissions();
if (p & QFileDevice::ReadOwner)
{
qDebug() << "Read file";
}
if (p & QFileDevice::WriteOwner)
{
qDebug() << "Write file";
}
if (p & QFileDevice::ExeOwner)
{
qDebug() << "Exec file";
}
output:
Read file
Write file
I tried with another variants like writeUser, but I get the same result.
Any idea or suggestion.
I'm using Windows 10.
Sorry, I can't share the file for testing.
I am not familiar with Qt, but this can be done with std::filesystem:
auto p = std::filesystem::status(file_name).permission();
if(p & std::filesystem::perms::owner_read) { ... }
if(p & std::filesystem::perms::owner_write) { ... }
if(p & std::filesystem::perms::owner_exec) { ... }
You can also create a filesystem::perms with the octal value:
if(p & std::filesystem::perms{0400}) { ... }
For more about different perms available values: https://en.cppreference.com/w/cpp/filesystem/perms

QTextStream is unable to write to file including "\t" with openmode QIODevice::Append

I tried to save some info to the text file using QTextStream. The code is given below:
QFile fi(QString("result.txt"));
fi.remove();
if(!fi.open(QIODevice::Append)) {
qDebug()<<"Cannot open file!";
return -1;
}
QTextStream ts(&fi);
float num = 1, error = 2;
ts<<"num="<<num<<"\t"<<"error="<<error<<endl;
However, the code does not work. The file is created, but nothing is written, i.e., the file is empty.
After some research, I found that I should change the open mode to QIODevice::Text | QIODevice::Append to make the code work. Otherwise the "\t" character must be removed. Does it mean that the QIODevice::Text is designed specifically for the special characters such as "\t" to work in writing to files?
I can't reproduce. The following works perfectly on Windows, OS X and Linux, with Qt 5.9. Please fix your example to be complete and reproducible. E.g. take the code below, and make it fail.
// https://github.com/KubaO/stackoverflown/tree/master/questions/stream-49779857
#include <QtCore>
QByteArray readAll(const QString &fileName) {
QFile f(fileName);
if (f.open(QIODevice::ReadOnly))
return f.readAll();
return {};
}
int main() {
auto tmp = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
auto fileName = QStringLiteral("%1/com.stackoverflow.questions.49779857-result.txt")
.arg(tmp);
QFile file(fileName);
file.remove();
if (!file.open(QIODevice::Append))
qFatal("Cannot open file!");
QTextStream ts(&file);
auto num = 1.0f, error = 2.0f;
ts << "num=" << num << "\t" << "error=" << error << endl;
file.close();
Q_ASSERT(file.exists());
Q_ASSERT(readAll(fileName) == "num=1\terror=2\n");
}

Qt (C++): QFile creates text file successfully but does not write to it

I have the following code, with which I am attempting to write to a file. When it is called, the file is created in the directory and the for-loop is entered. The values for in QVector<int> program also exist and are visible with qDebug(). However, after I close the file and the window, I check the file on my computer and it is completely empty. I have checked all over StackOverflow and the Qt forums and have yet to find a solution.
QString save_file = "C:/Users/MARVIN/Documents/Saddleback College/2015/Fall/CS3A/Semester Project/Emulator/hello.txt";
QFile file(save_file);
if(file.open(QFile::WriteOnly))
{
QTextStream out(&save_file);
out << "hello" << endl;
for(int i = 0; i < 100; i++)
{
out << program[i] << endl;
qDebug() << program[i] << endl;
}
file.close();
this->close();
}
Your issue:
QTextStream out(&save_file);
should be
QTextStream out(&file);

How can i open a file in visual c++?

I'm using visual studio and having problem opening this text file I've put it in the folder with all the source code yet i get an "No such file or directory" error. Here's my code
void Game::load_map(const char *filename)
{
int width,height,current;
std::ifstream in(filename);
if(in.fail()){
std::cout << "problem opening the file" <<std::endl;
perror(filename);
}
else
{
in >> width;
in >> height;
for(int i = 0; i < height; i++)
{
std::vector<int> vec;
for(int j = 0; j<width;j++)
{
if(in.eof())
{
std::cout<< "file ends error" << std::endl;;
return;
}
in >> current;
if(current>=0 && current<=1)
{
vec.push_back(current);
}else{
vec.push_back(0);
}
}
map.push_back(vec);
}
}
in.close();
}
and this how I'm calling this function:
load_map("map.map");
You program probably doesn't run in the same directory where the source code is placed, but rather in the Solution\Debug directory.
Either pass a file path relative to this directory to your function
load_map("..\\Project\\map.map");
or move the file you want to open there. Or 3rd option if you're not sure where you program's working directory is, provide a full path
load_map("c:\\Blah\\Blub\\Project\\map.map");

ofstream failing to create file when program runs with sudo

I'm writing an application that is using libusb, and I'm working on a section that involves writing the data of the devices to an XML file.
I've realised that the program will likely need to be run with sudo, as when I tried to transfer to a device there wasn't sufficient permissions. However, when I run the program with sudo, the ofstream will no longer create the file. Why is this, and how can I fix it?
int writeDeviceList(const char* fileName, libusb_device **devs, ssize_t deviceCount)
{
std::ofstream file;
file.open(fileName, std::ios::trunc);
if(!file)
{
//Code enters here when run with root
std::cout << "\"" << fileName << "\" file failed to open\n";
return -1;
}
file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
file << "<USB>\n";
ssize_t i;
for(i = 0; i < deviceCount; i++)
{
if(printdev(devs[i], &file) == -1)
{
return -1;
}
}
file << "</USB>\n";
file.close();
return 0;
}
One reason is if you are root on the local machine you run on, but the file is on an nfs mount of a remote machine, e.g. your normal user's home dir. Then root on the local machine will not be able to write or even open the file.