Extract absolute file path from a QRessource loaded file - c++

I have a file in /home/me/xmls/foo/bar.xml
and a correct qrc file containing this path
The folowing code :
QFileInfo f (":/foo/bar.xml");
cout<<f.absoluteFilePath().toAscii().data()<<endl;
outputs:
:/foo/bar.xml
when i was expecting:
/home/me/xmls/foo/bar.xml
Is there any way to recover the absolute path in the system of a QRessource loaded file ?

QResource encodes its contents into a file that gets compiled into the final binary. So, no I would expect it is not possible to get the original path at run time. As the Qt docs state: -
The Qt resource system is a platform-independent mechanism for storing binary files in the application's executable
Also, it doesn't make sense to want the original path, as other users are unlikely to have the file at that location.

This :
QFileInfo f (":/foo/bar.xml");
means that you are going to load a file from the resource file. Basically, this is a library (static or shared), which contains resources (images, translations, etc).
That is a standard syntax to access a file in the resources, as explained in their documentation for the resources.

Related

QIODevice::write : device not open

I've been trying to build a card game using Qt recently, but I come across a bug which is very weird.
QFile file(":/file/02");
file.open(QIODevice::ReadWrite|QIODevice::Truncate);
The return value of the second line is false. So when I try to read or write the file, this exception is thrown.
However,the file actually exists and a qrc file in the project writes like this:
<qresource prefix="/file">
<file alias="01">data.json</file>
<file alias="02">deck.json</file>
I've also run qmake after adding this qrc file, but everything remains the same. How can I fix it? Thanks a lot.
According to the docs:
The Qt resource system is a platform-independent mechanism for storing
binary files in the application's executable. This is useful if your
application always needs a certain set of files (icons, translation
files, etc.) and you don't want to run the risk of losing the files.
As it is part of the resource, the files are read only, so if you open it with write permission it will always return false.
In short the files stored in .qrc are static.

C++ getting real path of resource file

I have an external dll, who require a path as string to search the image.
Now I am able to save&load bitmap files from my resources, but I don't know how to get a path like "C:\test.bmp" from a resource file.
I already tried "test.bmp" (<- is the execute folder),
"resource\test.bmp" etc in upper, lowercase, + and without s and so on.
Any idea how I get a valid path to an image file in my resource?
testBMP = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BITMAP2));
That works file, but is sadly not what I can use :(
You can't get a file-path to a resource in your module, you have to use the Windows API calls. If you require the resource to have a file system path for the external dll you will need to extract it (this can be done at runtime) and save it into the file system.

C++ How should I send project that reads specific .txt files?

I have a c++ project that I would like to send to someone in executable form. The issue is the program must read from a .txt that I created (specific deliminators). Currently my program reads from a file path that is specific to my computer,
parseFile("/Users/David/Desktop/FinalProject/Store.txt");
How could I package the .txt file and the executable file together, where the exec. reads specifically from the that .txt on anyone's machine?
Note: I am using Xcode
Change your programs to receive 'file path' as a parameter. Write a note(ReadMe) with the program to specify the file format and added a sample data file with the package
tl;dr: if you just put the text file in the same folder with your executable, you can open it with parseFile("Store.txt");
In most runtime implementations, there is a notion of a "working directory." When you open up an executable via the graphical shell (by double clicking it or something to that effect) the working directory is the same as the directory the executable is in.
Now, if you try to open a file in your program via a path that isn't fully qualified, then the path that gets used will be relative to the working directory.
A fully qualified path is a discrete path that points to a single entity in your filesystem. "/Users/David/Desktop/FinalProject/Store.txt" is one such example, as it starts at root (/ on *nix, DriveLetter:\ on Windows) and says exactly which directories you need to traverse to get to your file.
A path that is not fully qualified (which basically means that it doesn't start at the root of your filesystem) can be used to perform relative file addressing. Most runtimes will assume that any path that is not fully qualified is meant to be relative to the working directory, which basically means that the path that actually gets opened is the result of concatenating your provided path to the end of the working directory.
As an example, if you opened your binary, which is stored as /Users/David/Desktop/FinalProject/a.exe, then the working directory would be set to /Users/David/Desktop/FinalProject/. If your program then tried to open "Store.txt", the runtime would see that you're trying to open a path that isn't fully qualified, so it would assume you meant to open a file relative to the working directory, which would then be /Users/David/Desktop/FinalProject/ + Store.txt, which would be /Users/David/Desktop/FinalProject/Store.txt.
The nice thing about this is that if you move your binary, the working directory moves too. if you move a.exe along with Store.txt to /Users/David/Desktop/FinalProject(copy)/, then when you open /Users/David/Desktop/FinalProject(copy)/a.exe, the working directory will be /Users/David/Desktop/FinalProject(copy)/ now, and now when you call parseFile("Store.txt"), it will instead open up /Users/David/Desktop/FinalProject(copy)/Store.txt. This holds true when moving to other computers, too.
It's worth noting that if your binary is run from a command line utility, the working directory will often be the directory the command line shell is in, rather than the executable's directory. It is, however, a part of the C standard that the first command line parameter to main() should be the name of the executable, and most implementations supply you with the fully qualified path. With some minimal parsing, you can use that to determine what path to use as a base for addressing files.

Qt, read in a local text file

I have tried to use QFile to open a text file:
I tried
QFile file("serial_deviceIP.txt");
but the file.open() returns false.
However, if I switched to a global address like:
QFile file("C:/Users/shupeng/Documents/qgroundcontrol_peidong_mod/serial_deviceIP.txt");
it works. Why? How can I solve this?
In the first instance, the path to the file cannot be found.
QFile file("serial_deviceIP.txt");
This specifies the file with a relative path, and will only work if serial_deviceIP.txt is in the current working directory, which is likely to be the directory that contains the executable of your program.
QFile file("C:/Users/shupeng/Documents/qgroundcontrol_peidong_mod/serial_deviceIP.txt");
This is referencing an absolute file path, so the file will be found
You can also use Qt's Resource System to bundle the files with your application.
Create a .qrc file in your project and add any file you wish to use/load in your application to it.
Then you can load your file as:
QFile file( ":myfiles/serial_deviceIP.txt" );
See QT Resource System for more information.
What happens is that when we are developing our code we usually keep our project source dir on mind as the reference so we don't give an absolute path, but after building the current directory will change and it will be the build directory, so our application won't find the files without a absolute path.
A possible solution is to add a Resources in our project including our project directory. So just add the following line in the project_file.pro:
RESOURCES += ./
and then use the character : before the file's name when you go to read it, like it:
QFile foo(":bar.txt")
That just work for read it but not for write. So to write is necessary specify an absolute path.

How to use QResource to read a file?

I've a text file which is added to a resource file in qt's pro file. I'd like to access this file via boost::filesystem. I've learned that I have to use QResource in order to do so, I've tried few things:
QResource resource("./Resources/setting_files/accepted_file_extensions.txt");
boost::filesystem3::ifstream fin(resource.absoluteFilePath().toStdString());
and it doesn't work, but why?
QResource is used for loading external binary resources which basically are files that are a compound of other several different files (images, documents, etc.).
The workflow is:
you create a resource file (.qrc extension) that specifies the files to be combined as a binary, using the specific Qt QRC markup tags;
you combine all the files in the resource data binary file using the command (for linux) rcc -binary myresource.qrc -o myresource.rcc;
finally you include the resource (dynamically) using a QResource instance by registering it through QResource::registerResource("/path/to/myresource.rcc"); .
This is very helpfull for importing several files using only one file. This is also very helpfull for embeded sytems.
Source: http://doc.qt.digia.com/qt/resources.html#external-binary-resources