How can I simultaneously read and write to binary files? I cannot seem to figure out why my program is erroring out and every bit of debugging I can think of does not yield me any good results. The program takes a string
and generates the file information to be written to a binary file. If the log binary exists, then the program compares the information from the file to the information in the log. If the information is different, then the program updates the log. The function I made is below:
#define SHADER_LOG "bin\\shader_log.bin"
void checkLog(const std::string& filename) {
std::string _path = std::filesystem::absolute(".\\shaders\\" + filename).string();
std::filesystem::file_time_type last_update = std::filesystem::last_write_time(_path);
std::pair<std::string, std::filesystem::file_time_type> fileInfo{filename, last_update};
std::cout << "File Info: { " << fileInfo.first << ", " << fileInfo.second << " }\n";
std::pair<std::string, std::filesystem::file_time_type> log_entry;
memset(&log_entry, 0, sizeof(log_entry));
if (!std::filesystem::exists(SHADER_LOG)) {
std::ofstream log(SHADER_LOG, std::ios_base::out | std::ios::binary);
log.write(reinterpret_cast<const char*>(&fileInfo), sizeof(fileInfo));
log.close();
return;
}
std::fstream log(SHADER_LOG, std::ios_base::in | std::ios_base::out | std::ios::binary);
if (!log.is_open()) {
throw std::runtime_error(std::format("Failed to open {}!", SHADER_LOG));
}
int i = 0;
while (!log.eof()) {
log.read(reinterpret_cast<char*>(&log_entry), sizeof(log_entry));
//log.getline(reinterpret_cast<char*>(&log_entry), sizeof(log_entry));
i++;
if ((log_entry.first == fileInfo.first) && (log_entry.second != fileInfo.second))
{// Update log entry
log.write(reinterpret_cast<const char*>(&fileInfo), sizeof(fileInfo));
std::cout << "Log Entry: { " << log_entry.first << ", " << log_entry.second << " }\n";
std::cout << "Log successfully updated!\n";
}
else
{// Print to manually confirm update status
std::cout << "Log Entry: { " << log_entry.first << ", " << log_entry.second << " }\n";
std::cout << std::format("{} is up to date.\n", log_entry.first);
std::cout << i << std::endl; // debugging number of times the loop is run
}
}
log.close();
if (!log.is_open()) {
std::cout << std::format("{} file closed successfully!\n", SHADER_LOG);
}
return; // trying to debug exiting the function
}
On first run, the function seems to work as expected. However, on the second run, the program exits unexpectedly and gives the error code:
(process 14128) exited with code -1073741819.
After updating the file to be logged, the function exits without the above code, but the informtion printed to the console reveals more information about the problem:
Log Entry: { , 1601-01-01 00:00:00.0000000 }
is up to date.
The above is printed some 86 times before the function exits without returning any errors.
I tried condensing the function down to the function below to try and reveal something more about the problem:
void checkLog(const std::string& filename) {
std::string _path = std::filesystem::absolute(".\\shaders\\" + filename).string();
std::filesystem::file_time_type last_update = std::filesystem::last_write_time(_path);
std::pair<std::string, std::filesystem::file_time_type> fileInfo{filename, last_update};
std::cout << "File Info: { " << fileInfo.first << ", " << fileInfo.second << " }\n";
std::pair<std::string, std::filesystem::file_time_type> log_entry;
memset(&log_entry, 0, sizeof(log_entry));
if (!std::filesystem::exists(SHADER_LOG)) {
std::fstream log(SHADER_LOG, std::ios_base::out | std::ios_base::in | std::ios::binary);
log.write(reinterpret_cast<const char*>(&fileInfo), sizeof(fileInfo));
log.seekp(0); // tried .seekp and .seekg
/* Debugging */
std::pair<std::string, std::filesystem::file_time_type> log_entry {};
memset(&log_entry, 0, sizeof(log_entry)); // Read in another stack thread to clear memory to avoid alignment errors
log.getline(reinterpret_cast<char*>(&log_entry), sizeof(log_entry));
std::cout << "Log Entry: { " << log_entry.first << ", " << log_entry.second << " }\n";
log.close();
return;
}
}
This did give me some more information about what could be causing the problem, but I am still at a loss for the solution. The output of the condensed version indicates that my program is unable to write to the log file:
File Info: { shader.comp, 2023-08-15 00:43:48.7875194 }
Log Entry: { , 1601-01-01 00:00:00.0000000 }
is up to date.
Please help me. I cannot figure out what I am doing wrong and I'm starting to think that it's not possible to read and write to a binary file simultaneously.
Edit:
int main() {
try {
checkLog("shader.comp");
std::cout << "Exited Compiler successfully!\n";
/* When it gives the error code, it does not print the above line to the console */
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}