Created
July 17, 2020 12:13
-
-
Save KmolYuan/7cdaa3315a42433e692b6f3a65e35005 to your computer and use it in GitHub Desktop.
Save structure to a binary file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <fstream> | |
#include <iostream> | |
#include <tuple> | |
#include <vector> | |
using namespace std; | |
using array1d = vector<double>; | |
using array2d = vector<array1d>; | |
using array3d = vector<array2d>; | |
// Avoid duplicate naming | |
namespace { | |
const auto FILE_NAME = "data.bin"; | |
// Get the shape of arrays | |
tuple<size_t, size_t, size_t> get_shape(array3d &vec) { | |
return {vec.size(), vec[0].size(), vec[0][0].size()}; | |
} | |
// Copy vector into an 1d pointer | |
double *dump_3d(array3d &vec, size_t ind1d, size_t ind2d, size_t ind3d) { | |
auto ptr = new double[ind1d * ind2d * ind3d]; | |
for (auto i = 0u; i < ind1d; i++) | |
for (auto j = 0u; j < ind2d; j++) | |
for (auto k = 0u; k < ind3d; k++) | |
ptr[(i * ind2d + j) * ind3d + k] = vec[i][j][k]; | |
return ptr; | |
} | |
// load 1d pointer to a vector | |
void load_3d(const double *ptr, array3d &vec, size_t ind1d, size_t ind2d, | |
size_t ind3d) { | |
array3d vec_new(ind1d, array2d(ind2d, array1d(ind3d))); | |
for (auto i = 0u; i < ind1d; i++) | |
for (auto j = 0u; j < ind2d; j++) | |
for (auto k = 0u; k < ind3d; k++) | |
vec_new[i][j][k] = ptr[(i * ind2d + j) * ind3d + k]; | |
// Swap to current vector | |
vec.swap(vec_new); | |
} | |
} // namespace | |
// Simple data format without array | |
struct Base { | |
int age = 0; | |
}; | |
// Full data format in calculation | |
struct Student : Base { | |
// Array data (dynamic space) | |
array3d grades; | |
// Data creation (blank) | |
Student() : Base{} { grades = {}; } | |
// Create from a base class pointer | |
explicit Student(Base *me) : Base(*me) { grades = {}; } | |
}; | |
int main() { | |
// Try to delete cache file if exist | |
remove(FILE_NAME); | |
size_t ind1d, ind2d, ind3d; | |
{ | |
// Get dynamic dimension | |
array3d example_array = {{{0, 0, 0}, {0, 0, 0}}, {{0, 0, 0}, {0, 0, 0}}}; | |
auto size3d = get_shape(example_array); | |
// C++17 | |
// auto [ind1d, ind2d, ind3d] = get_array3d_size(student.grades); | |
ind1d = get<0>(size3d); | |
ind2d = get<1>(size3d); | |
ind3d = get<2>(size3d); | |
} | |
size_t array3d_size = ind1d * ind2d * ind3d; | |
ofstream output_file(FILE_NAME, ios::binary | ios::out); | |
double *tmp; | |
for (auto i = 0; i < 500; i++) { | |
// Calculation | |
// Data creation -> delete after current step | |
Student student; | |
student.age = (20 + i) % 90; | |
student.grades = {{{1, 2, 3}, {4, 5, 6}}, {{7, 8, 9}, {10, 11, 12}}}; | |
// Transfer members create from the method | |
tmp = dump_3d(student.grades, ind1d, ind2d, ind3d); | |
// Write by base size | |
output_file.write((char *)&student, sizeof(Base)); | |
// Write array data | |
output_file.write((char *)tmp, sizeof(double[array3d_size])); | |
// Clear cache | |
delete tmp; | |
} | |
output_file.close(); | |
ifstream input_file(FILE_NAME, ios::binary | ios_base::in); | |
auto buffer = new Base; | |
auto id = 0u; | |
// Read until next character is the end of file (EOF) | |
while (input_file.peek() != EOF) { | |
// Read basic data | |
input_file.read((char *)buffer, sizeof(Base)); | |
// Require space to save array data | |
tmp = new double[array3d_size]; | |
// Read array data | |
input_file.read((char *)tmp, sizeof(double[array3d_size])); | |
// Re-build class from Base buffer | |
Student student(buffer); | |
// Load array from pointer | |
load_3d(tmp, student.grades, ind1d, ind2d, ind3d); | |
// Clear cache (grades is transferred) | |
delete tmp; | |
// Show data | |
cout << "ID: " << id++ << endl; | |
cout << "Age: " << buffer->age << endl; | |
cout << "Grades:"; | |
for (auto &iter1d : student.grades) | |
for (auto &iter2d : iter1d) { | |
for (auto elem : iter2d) | |
cout << " " << elem; | |
cout << ";"; | |
} | |
cout << endl; | |
} | |
delete buffer; | |
input_file.close(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment