C++点云大文件读取

news/2024/12/23 1:57:36/

C++点云大文件读取

  • 1. 常规读取
    • 1.1 逐行读取
    • 1.2 逐字节读取
  • 2. 并行读取 (Multithreading)
  • 3. 使用缓冲读取 (Buffered I/O)
  • 4. 内存映射文件 (Memory Mapping)

在C++中读取大文件时,如果需要提高读取速度,可以考虑以下几种方法:

1. 常规读取

常规读取是指直接使用 std::ifstream 或 std::getline 逐个字符或逐行读取文件。适用于小文件或需要逐行处理内容的场景。

1.1 逐行读取

#include <iostream>
#include <fstream>
#include <string>void read_large_file(const std::string& filename) {std::ifstream file(filename);if (!file) {std::cerr << "Failed to open file" << std::endl;return;}std::string line;while (std::getline(file, line)) {// 处理读取的行}file.close();
}

1.2 逐字节读取

#include <iostream>
#include <fstream>void read_large_file(const std::string& filename) {std::ifstream file(filename, std::ios::binary);if (!file) {std::cerr << "Failed to open file" << std::endl;return;}char byte;while (file.get(byte)) {// 处理读取的字节}file.close();
}

2. 并行读取 (Multithreading)

对于大文件,如果处理的内容可以并行化(例如按行、按块处理),可以使用多线程来加速读取过程。在多核处理器上,这种方法能够显著提升文件读取的性能。可以使用标准库的 std::thread 或者并行框架如 OpenMP、TBB 等来实现。

复制代码
#include <iostream>
#include <fstream>
#include <vector>
#include <thread>void process_chunk(const std::vector<char>& buffer, size_t start_idx, size_t end_idx) {// 处理 buffer[start_idx, end_idx] 范围内的数据
}void read_large_file(const std::string& filename) {std::ifstream file(filename, std::ios::binary);if (!file) {std::cerr << "Failed to open file" << std::endl;return;}file.seekg(0, std::ios::end);size_t file_size = file.tellg();file.seekg(0, std::ios::beg);size_t chunk_size = file_size / 4;  // 假设使用 4 个线程std::vector<std::thread> threads;for (size_t i = 0; i < 4; ++i) {size_t start_idx = i * chunk_size;size_t end_idx = (i + 1) * chunk_size;if (i == 3) end_idx = file_size;std::vector<char> buffer(chunk_size);file.seekg(start_idx, std::ios::beg);file.read(buffer.data(), chunk_size);threads.push_back(std::thread(process_chunk, std::ref(buffer), start_idx, end_idx));}for (auto& t : threads) {t.join();}file.close();
}

3. 使用缓冲读取 (Buffered I/O)

使用缓冲区可以减少频繁的磁盘 I/O 操作,从而加速文件读取过程。C++ 标准库中的 std::ifstream 默认使用缓冲读取。你可以通过调整缓冲区的大小来优化性能。比如,可以使用 std::ifstream 配合 std::vector 来增加读取块的大小。

  • 缓冲区大小的经验值
    对于较小的文件(几 MB),可以选择几 KB 到几十 KB 的缓冲区。
    对于较大的文件(几十 MB 到几 GB),可以选择较大的缓冲区(几百 KB 到 1MB)。
  • 内存的限制
    缓冲区大小也需要考虑系统的内存使用情况。对于非常大的文件(如 10 GB 或更大),如果缓冲区太大,可能会导致内存不足,从而影响系统的性能。根据系统内存选择合理的大小。

示例代码

#include <iostream>
#include <fstream>
#include <vector>void read_large_file(const std::string& filename) {std::ifstream file(filename, std::ios::binary);if (!file) {std::cerr << "Failed to open file" << std::endl;return;}// 设置一个合适大小的缓冲区,比如 1MBstd::vector<char> buffer(1024 * 1024);while (file.read(buffer.data(), buffer.size())) {// 处理读取的数据// 可以根据需求处理 buffer}// 读取剩余的部分if (file.gcount() > 0) {// 处理剩余的数据// 可以根据需求处理 buffer 中的数据}file.close();
}

4. 内存映射文件 (Memory Mapping)

内存映射文件通过将文件的内容映射到进程的内存空间,可以避免频繁的 I/O 操作,提高文件读取的效率。在大文件处理时,内存映射尤其有用。

  • 缺点
    对于大于10G的文件,当内存不足时会导致读取不全的问题
    该方法不支持长路径,不支持中文路径(本人测试了很多方法,均不成功)
#include <iostream>
#include <fstream>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>void read_large_file(const std::string& filename) {int fd = open(filename.c_str(), O_RDONLY);if (fd == -1) {std::cerr << "Failed to open file" << std::endl;return;}off_t file_size = lseek(fd, 0, SEEK_END);lseek(fd, 0, SEEK_SET);void* mapped_mem = mmap(nullptr, file_size, PROT_READ, MAP_PRIVATE, fd, 0);if (mapped_mem == MAP_FAILED) {std::cerr << "Failed to map file to memory" << std::endl;close(fd);return;}// 使用映射的内存读取文件内容char* file_data = static_cast<char*>(mapped_mem);// 可以直接处理 file_data// 完成后解除映射munmap(mapped_mem, file_size);close(fd);
}

http://www.ppmy.cn/news/1557339.html

相关文章

二叉树 -- 堆(详解)

目录 1、堆的概念及结构 2、堆的实现(附代码) 2.1、向下调整算法建堆 3、堆的应用(附代码) 3.1、堆排序 3.2、TOP-K问题 1、堆的概念及结构 如果有一个关键码的集合K { k0&#xff0c;k1 &#xff0c;k2 &#xff0c;…&#xff0c;k(n-1) }&#xff0c;把它的所有元素…

防止私接小路由器

电脑获取到IP地址不是DHCP服务器的IP地址段&#xff0c;导致整个公司网络瘫痪&#xff0c;这些故障现象通常80%原因是私接小路由器导致的&#xff0c;以下防止私接小路由器措施。 一、交换机配置DHCP Sooping DHCP snooping是一种DHCP安全特性&#xff0c;用于防止非法设备获…

安装openGauss数据库一主一备

安装openGauss数据库一主一备 一.安装准备1.修改/etc/selinux/config文件中的“SELINUX”值为“disabled”。2.重新启动操作系统。3.检查防火墙是否关闭。4.关闭防火墙并禁止开机重启。5.关闭交换内存6.设置主机名7.设置解析主机名和 IP 地址8.安装相关依赖包9.创建单独的用户组…

CoinShares预测2025年加密市场前景看涨

原文来源&#xff1a;CoinShares预测2025年加密市场前景看涨 - 币热网 - 区块链数字货币新闻消息资讯 欧洲加密投资公司CoinShares发布了2025年的市场预测&#xff0c;概述了可能塑造行业的关键趋势。 报告指出&#xff0c;在即将上任的川普政府下&#xff0c;监管环境将更加…

信息安全管理与评估赛题第7套

全国职业院校技能大赛 高等职业教育组 信息安全管理与评估 赛题七 模块一 网络平台搭建与设备安全防护 1 赛项时间 共计180分钟。 2 赛项信息 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段 网络平台搭建与设备安全防护 任务1 网络平台搭建 XX:XX- XX:XX 50 任务2…

202411 第十六届蓝桥杯青少组 STEMA 考试真题 汇总

2024年11月 第十六届 蓝桥杯青少组 STEMA测评考试&#xff0c;包含scratch图形化编程&#xff0c;Python&#xff0c;C&#xff0c;microbit&#xff0c;EV3&#xff0c;arduino&#xff0c;计算思维U12,U8,U10等真题汇总。 202411 蓝桥杯青少组 STEMA测评 Scratch 试题 20241…

如何使用 Python 连接 MySQL 数据库?

在Python开发中&#xff0c;连接MySQL数据库是一个常见的需求。 我们可以使用多种库来实现这一功能&#xff0c;其中最常用的是mysql-connector-python和PyMySQL。 下面我将详细介绍如何使用这两个库来连接MySQL数据库&#xff0c;并提供一些实际开发中的建议和注意事项。 1…

华为云stack网络服务流量走向

1.同VPC同子网同主机内ECS间互访流量走向 一句话通过主机内部br-int通信 2.同VPC同子网跨主机ECS间互访流量走向 3.同VPC不同子网同主机ECS间互访流量走向 去往本机的mac地址都记录在br-tun流表里 4.同VPC不同子网跨主机ECS间互访流量走向 5.对等连接流量走向&#xff08;跨V…