Loading files merged with executable - c++

I'm trying to merge a file with my executable, and read the merged file. I merge them with the Windows command;
copy /b Game.exe+Image.jpg TheGame.exe
Here's what I've tried:
std::ifstream f("Image.jpg");
if (f.good()) {
std::cout << "Found Image.jpg" << std::endl;
}
Image.jpg is in the same directory as the resulting executable file, and it works. However when I use the command to merge them and then delete the Image.jpg file it is not found (although it is merged with the executable.)
Any suggestions?

ifstream only works with external files. You deleted the file it is trying to open, so of course it will not find the file. What you are attempting cannot (easily) be done using binary merges. If you want to store a file inside of an executable, the correct approach is to store it in a resource instead. Read the following chapter on MSDN for more information.
Introduction to Resources
In particular, the following example shows how go create a new resource in an .exe file and write data into it. The example copies a resource from another .exe file, but you can write whatever you want. In tbis case, replace RT_DIALOG with RT_RCDATA, and write your image data.
Using Resources

Related

Downloading my programs data from a webserver (Its basically just a .exe turned into .txt) but when I put it into a .exe it does not run?

So currently I am using a basic Http request to pull the exe data from my server weblink.com/Program.exe
it returns my program in .txt form but when I put it into a file it will not run.
I assume this is because I need metadata but have no clue how to find that process or even how to google something as specific as that... So I am either asking for a solution (how to add proper .exe metadata) or if there is a better way to download files like that in C++
*Note I cannot use basic windows functions such as DownloadToFileA or External Library's (Like LibCurl/Curl)
OutFile.open(XorStr("C:\\Users\\Program.exe").c_str(), std::ios::out);
if (OutFile.is_open())
{
OutFile << Output;
//Initialize .exe Meta Data???
}
OutFile.close();
You need to open your file in binary mode otherwise newline translation will screw up your executable:
OutFile.open(XorStr("C:\\Users\\Program.exe").c_str(), std::ios::out | std::ios::binary);

C++ How to get folder information such as names and sizes

I need to make a program that will output all the folders and folder sizes that are in the same directory as the executable file, and when you execute it via command prompt it should display all the folders that are in the same directory as it, for example. the finished executable file of the c++ program would be able to be moved into the documents folder and all folders that were in the documents folder would be outputted when you execute the file through command prompt. what I do know is that I will probably have to make a vector or some sort of container to hold the folder names and folder sizes and output it using a ranged for loop, there are also commmand line arguments that can be used to modify how the information is outputted such as the folders are sorted alphabetically and what not. I should be able to do that, I just do not know how exactly I can go about pulling folder information in c++. If I know how exactly to get the folder names and sizes I can start doing the rest. Any help would be appreciated about how I can go about doing this.
Most of what you want to do can be done using std::filesystem in C++17
You can get the current path using current_path() and you can then loop over everything contained in a directory using directory_iterator(). file_size() can be used to get the size of a file.
auto path = std::filesystem::current_path();
for (auto& obj : std::filesystem::directory_iterator(path)) {
// Get size of files
if (!std::filesystem::is_directory(obj)) {
auto size = std::filesystem::file_size(obj);
}
// Do other things
// ...
}
If you are able to use C++17 std::filesystem is definitely the way to go.

How to convert Qt file path from resource to absolute path?

I need to receive the absolute file path like
C:/Users/Dima/YandexDisk/_Application/WeldAnalysis/ExperimentDefaults.xlsx
from path of QRC file like
:/Data/ExperimentDefaults.xlsx.
How can I do this?
Resources are packed all together into the QRC file, they are not exposed to the filesystem, thus they cannot be converted to a standard path; it is like accessing a file inside a zip file.
What are you willing to do with such file path? QFile can deal with resource paths (":/...") and open such files, but other file handling APIs don't (such as C's fopen or C++'s std::ifstream). Also, and for the same reason, non-Qt application won't be able to open such files if passed as a parameter.
Options you have include:
opening the file using QFile and read it using related Qt classes (given you are dealing with an Excel file I think it doesn't worth the effort, unless you have some library to read it from a memory buffer).
copying the file out of the resources container to a temporary directory (you can use QTemporaryDir to create one), and use the file from there:
QTemporaryDir tempDir;
if (tempDir.isValid()) {
const QString tempFile = tempDir.path() + "/yourfile.xlsx";
if (QFile::copy(":/yourfile.xlsx", tempFile)) {
// your file is now extracted to the filesystem
}
}
Only be aware that when tempDir is destroyed, the temporary directory is also deleted, therefore your file. You can avoid this by disabling the auto-remove feature: tempDir.setAutoRemove(false) and manually deleting the temporary directory when you finish with the extracted file.

C++ ifstream tries to open file while being written

I am polling a directory constantly for files and every time I see a file that meets some certain criteria for reading, I open the file and parse it.
string newLine;
ifstream fileReader;
fileReader.open(filename.c_str());
while(!fileReader.eof())
{
getline(fileReader, newLine);
// do some stuff with the line...
}
filereader.close();
The above code is in a loop that runs every 1 second checking a directory for new files. My issue is that as I am transferring files into the folder for processing, my loop finds the file and passes the name of the file to ifstream who then opens it and tries to parse an incomplete file. How do I make ifstream wait until the file is done being written before it tries to parse the file?
EDIT:
Wanted to better word the issue here since a replier seems to have misunderstood my issue. I have 2 directories
mydirectory/
mydirectoryParsed/
THe way my code works is that my program checks for files in mydirectory/ and when it finds them, parses them and uses the information in the files. No writing to the files are done. Once I am done parsing the file, the file is moved to mydirectoryparsed/
The issue is that when I transfer files over the network into mydirectory/ the ifstream sees these files midtransfer and starts reading them before they finish writing to the directory. How do I make ifstream wait until the file is completely written before parsing it?
Don't transfer the files directly into the directory that your program is watching; instead, transfer them into a different directory on the same drive, and then when the transfer is done, move them into the watched directory. That way, the complete file appears in the watched directory in a single atomic operation.
Alternatively, you could use a naming convention in the watched directory — append a suffix like ".partial" to files that are being transferred, and then rename the file to remove the suffix when the transfer is done. Have your program ignore files whose names end with the suffix.
You're not supposed to open the file every time you write in it. Open it once!
Some pseudo-code for this would be :
1- Open file
2- Get the data you want to write, treat that data
3- Call the write to file function
4- Loop until you have nothing left to write
5- Close de file

How to prevent iostreams::mapped_file_sink from creating executable txt files

EDIT: code sample is broken, it is missing .is_open(), please DON'T use it.
I have a rather strange question. I use boost iostreams and they work awesome, but the problem is that files that program creates are executable txt files(I'm on ubuntu,msg is :""lol2.txt" is an executable text file.").
So is there any way to make it a regular nonexecutable file. I would like to change the code so that it doesnt create executable, files I know I can change the file after it is created from terminal or Nautilus.
btw this is the code that I'm using:
void write_file(const std::string& name,string data)
{
iostreams::mapped_file_params params;
params.new_file_size=data.size();
params.path=name;
iostreams::mapped_file_sink file(params);
memcpy(file.data(),&data[0],data.size());
}
You can change the file creation mask of your process to create non-executable files by default:
umask(getumask() & ~(S_IXUSR | S_IXGRP | S_IXOTH));