C++高效读取大规模文本格式点云(windows)

需使用VS2017及以上版本,C++语言标准选择C++17,支持OpenMP。

执行效率明显优于ifstream + stof。

// 点云数据结构
struct PointXYZ {
	std::array<float, 3> coord;  
};


float string_to_float_fast(const std::string& str) {
	float value;
	auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
	if (ec != std::errc()) {
		// 处理错误(如非数字字符串)
		return 0.0f; // 或抛出异常
	}
	return value;
}

uint8_t string_to_uchar_fast(const std::string& str) {
	unsigned int value;
	auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
	if (ec != std::errc() || value > 255) {
		return 0; // 错误处理
	}
	return static_cast<uint8_t>(value);
}

bool read_pointcloud_parallel(const std::string& filename, std::vector<PointData>& cloud) {
    struct CSVRow {
	    std::string col1, col2, col3;
    };

	// --- 1. 打开文件并内存映射 ---
	HANDLE hFile = CreateFileA(
		filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,
		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE) {
		//throw std::runtime_error("Failed to open file");
		printf("Failed to open file");
		return false;
	}

	DWORD fileSize = GetFileSize(hFile, NULL);
	HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
	if (hMapping == NULL) {
		CloseHandle(hFile);
		printf("Failed to create file mapping");
		return false;
		//throw std::runtime_error("Failed to create file mapping");
	}

	const char* mappedData = static_cast<const char*>(
		MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, fileSize));
	if (mappedData == NULL) {
		CloseHandle(hMapping);
		CloseHandle(hFile);
		throw std::runtime_error("Failed to map view of file");
	}

	// --- 2. 分块并行解析 ---
		std::vector<CSVRow> rows;
	rows.reserve(1000000); // 预分配

//#pragma omp parallel
	{
		// 每个线程处理一块数据
		int numThreads = omp_get_num_threads();
		int threadId = omp_get_thread_num();
		size_t chunkSize = fileSize / numThreads;
		size_t start = threadId * chunkSize;
		size_t end = (threadId == numThreads - 1) ? fileSize : (threadId + 1) * chunkSize;

		// 调整起始位置到行首
		if (threadId != 0) {
			while (start < fileSize && mappedData[start] != '\n') start++;
			if (start < fileSize) start++;
		}

		// 解析当前块
		std::vector<CSVRow> localRows;
		size_t pos = start;
		while (pos < end) {
			size_t lineEnd = pos;
			while (lineEnd < fileSize && mappedData[lineEnd] != '\n') lineEnd++;

			std::string line(mappedData + pos, lineEnd - pos);
			pos = lineEnd + 1;

			// 分号分割3列
			size_t col1End = line.find(';');
			size_t col2End = line.find(';', col1End + 1);

			if (col3End != std::string::npos) {
//#pragma omp critical
				rows.emplace_back(CSVRow{
					line.substr(0, col1End),
					line.substr(col1End + 1, col2End - col1End - 1),
					line.substr(col2End + 1)
					});
			}
		}
	}

	// --- 3. 清理资源 ---
	UnmapViewOfFile(mappedData);
	CloseHandle(hMapping);
	CloseHandle(hFile);

	cloud.resize(rows.size());
#pragma omp parallel for
	for (int i = 0;i < rows.size();i++)
	{
		cloud[i].coord[0] = string_to_float_fast(rows[i].col1);
		cloud[i].coord[1] = string_to_float_fast(rows[i].col2);
		cloud[i].coord[2] = string_to_float_fast(rows[i].col3);
	}

	return true;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值