提问人:Guled 提问时间:10/31/2022 更新时间:10/31/2022 访问量:101
读取巨大的二进制文件 (~1.5 GB) 并将结果写入文本文件 C++
Reading huge binary file (~1.5 GB) and writing the results to a text file C++
问:
我正在尝试逐块读取一个巨大的二进制文件,解码每个块并将其输出到文本文件中,以便于故障排除。到目前为止,我已经编写了一个代码来做到这一点,但它非常慢(需要几个小时才能解码整个文件)。
这是我的代码:
template<class T> std::vector<T> readBytes(std::ifstream& input, int numOfBytes) {
std::vector<T> output;
output.reserve(numOfBytes);
T* buf = new T[numOfBytes];
input.read((char*)buf, sizeof(T) * numOfBytes);
for (int i = 0; i < numOfBytes; ++i) {
output.push_back(buf[i]);
}
delete[] buf;
return output;
}
std::ifstream file("lidar_Mission.dat", std::ios::binary | std::ios::ate);
std::streampos total_bytes(file.tellg());
file.seekg(12, std::ios::beg); //skip the header
while (file) {
if (file.good()) {
//Read the required chunk and store it in a vector
std::vector<std::int8_t> time(readBytes<std::int8_t>(file, 8));
std::vector<std::int8_t> lidarx(readBytes<std::int8_t>(file, 4));
std::vector<std::int8_t> lidary(readBytes<std::int8_t>(file, 4));
std::vector<std::int8_t> lidarz(readBytes<std::int8_t>(file, 4));
std::vector<std::int8_t> intensity(readBytes<std::int8_t>(file, 2));
std::vector<char> classification(readBytes<char>(file, 1));
std::vector<char> Return_scan(readBytes<char>(file, 1));
uint8_t timeArr[8] = { time[0], time[1],time[2],time[3],time[4],time[5],time[6],time[7] };
uint8_t lidarxArr[4] = { lidarx[0], lidarx[1],lidarx[2],lidarx[3] };
uint8_t lidaryArr[4] = { lidary[0], lidary[1],lidary[2],lidary[3] };
uint8_t lidarzArr[4] = { lidarz[0], lidarz[1],lidarz[2],lidarz[3] };
uint8_t intenArr[2] = { intensity[0], intensity[1] };
uint8_t clssArr[1] = { classification[0]};
uint8_t Retn_scnArr[1] = { Return_scan[0]};
//Type punning
double timestamp = *((double*)&timeArr);
float x = *((float*)lidarxArr);
float y = *((float*)lidaryArr);
float z = *((float*)lidarzArr);
uint16_t inten = *((uint16_t*)intenArr);
uint8_t clss = *((uint8_t*)clssArr);
uint8_t Retn_scn = *((uint8_t*)Retn_scnArr);
//Write to a text file
std::ofstream fout;
fout.open("test2", std::ios::out | std::ios::app);
fout << std::fixed << std::setprecision(9) << std::left << std::setw(19) << timestamp
<< std::setprecision(10) << std::setw(15) << x
<< std::setprecision(10) << std::setw(15) << y
<< std::setw(16) << z
<< std::setw(10) << inten
<< std::endl;
fout.close();
}else{
throw std::exception();
}
}
关于如何让它运行得更快的任何想法?谢谢
答:
0赞
psimpson
10/31/2022
#1
尽可能多地在循环外执行操作,尤其是 I/O。在进入循环之前打开一次,退出循环后关闭一次。如果出现任何致命错误,也要关闭文件,并指示操作失败的原因。
您还可以测试将其他声明移到循环之外,引用其中的预定义变量。如果您不确定编译器是否可以优化类似的东西,那么这是一个易于运行的测试。
评论
0赞
Guled
10/31/2022
谢谢@psimpson。一定会尝试的。
评论
read()
是一项高开销操作。尝试读取较大的块文件并在这些块中工作。new
delete
resize
struct
double, float, float, float, uint16_t, uint8_t, uint8_t