C++点云大文件读取

news2024/12/22 21:54:16

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;
    }

    // 设置一个合适大小的缓冲区,比如 1MB
    std::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.coloradmin.cn/o/2263911.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PC寄存器(Program Counter Register) jvm

在JVM&#xff08;Java虚拟机&#xff09;中&#xff0c;PC寄存器&#xff08;Program Counter Register&#xff09;扮演着至关重要的角色&#xff0c;它是JVM执行引擎的核心组成部分之一。以下是PC寄存器在JVM中的具体角色和职责&#xff1a; 指令执行指针&#xff1a; PC寄存…

线性分类器(KNN,SVM损失,交叉熵损失,softmax)

KNN 工作机制 k-近邻算法的工作机制可以分为两个主要阶段&#xff1a;训练阶段和预测阶段。 训练阶段 在训练阶段&#xff0c;k-近邻算法并不进行显式的模型训练&#xff0c;而是简单地存储训练数据集。每个样本由特征向量和对应的标签组成。此阶段的主要任务是准备好数据&…

重拾设计模式--适配器模式

文章目录 适配器模式&#xff08;Adapter Pattern&#xff09;概述适配器模式UML图适配器模式的结构目标接口&#xff08;Target&#xff09;&#xff1a;适配器&#xff08;Adapter&#xff09;&#xff1a;被适配者&#xff08;Adaptee&#xff09;&#xff1a; 作用&#xf…

StarRocks:存算一体模式部署

目录 一、StarRocks 简介 二、StarRocks 架构 2.1 存算一体 2.2 存算分离 三、前期准备 3.1前提条件 3.2 集群规划 3.3 配置环境 3.4 准备部署文件 四、手动部署 4.1 部署FE节点 4.2 部署BE节点 4.3 部署CN节点&#xff08;可选&#xff09; 4.4 FE高可用…

找数字:JAVA

题目描述 试计算在区间1 到n 的所有整数中&#xff0c;数字x&#xff08;0 ≤ x ≤ 9&#xff09;共出现了多少次&#xff1f; 例如&#xff0c;在1到11 中&#xff0c;即在1、2、3、4、5、6、7、8、9、10、11 中&#xff0c;数字1 出现了4 次。 输入描述: 输入共1行&#xf…

AI的使用:结构化提示词

根据自己的使用&#xff0c;不断的完善自己的提示词。并且像程序版本一样管理和迭代自己的提示词&#xff0c;这样才能准确的按照自己的目的去使用AI。而为了更好的管理&#xff0c;我们在一开始使用的时候&#xff0c;就要有一个易于管理的定义&#xff0c;即&#xff1a;结构…

Netcat:网络中的瑞士军刀

免责声明&#xff1a;使用本教程或工具&#xff0c;用户必须遵守所有适用的法律和法规&#xff0c;并且用户应自行承担所有风险和责任。 文章目录 一、引言二、简述三、Netcat功能&#xff1f;四、参数选项五、Netcat 的常见功能六、高级用法多连接处理创建简单的代理 七、Netc…

VS Code Copilot 与 Cursor 对比

选手简介 VS Code Copilot&#xff1a;算是“老牌”编程助手了&#xff0c;虽然Copilot在别的编辑器上也有扩展&#xff0c;不过体验最好的还是VS Code&#xff0c;毕竟都是微软家的所以功能集成更好一些&#xff1b;主要提供的是Complete和Chat能力&#xff0c;也就是代码补全…

28、基于springboot的房屋租赁系统

房屋是人类生活栖息的重要场所&#xff0c;随着城市中的流动人口的增多&#xff0c;人们对房屋租赁需求越来越高&#xff0c;为满足用户查询房屋、预约看房、房屋租赁的需求&#xff0c;特开发了本基于Spring Boot的房屋租赁系统。 本文重点阐述了房屋租赁系统的开发过程&…

【Qt】显示类控件:QLabel、QLCDNumber、QProgressBar、QCalendarWidget

目录 QLabel QFrame 例子&#xff1a; textFormat pixmap、scaledContents alignment wordWrap、indent、margin buddy QLCDNumber 例子&#xff1a; QTimer QProgressBar 例子&#xff1a; QCalendarWidget 例子&#xff1a; QLabel 标签控件&#xff0c;用来显示…

基于STM32的自学习智能小车设计

目录 引言系统设计 硬件设计软件设计系统功能模块 传感器模块控制模块自学习算法模块系统实现 硬件实现软件实现测试与优化结论与展望 1. 引言 随着人工智能和机器学习技术的不断发展&#xff0c;越来越多的智能小车开始实现自主学习与行为决策。传统的智能小车通常依靠固定的…

Android OpenGLES2.0开发(九):图片滤镜

“当你改变想法的时候&#xff0c;记得也要改变你的世界。”——诺曼文森特皮尔 Android OpenGLES开发&#xff1a;EGL环境搭建Android OpenGLES2.0开发&#xff08;一&#xff09;&#xff1a;艰难的开始Android OpenGLES2.0开发&#xff08;二&#xff09;&#xff1a;环境搭…

梳理你的思路(从OOP到架构设计)_简介设计模式

目录 1、 模式(Pattern) 是较大的结构​编辑 2、 结构形式愈大 通用性愈小​编辑 3、 从EIT造形 组合出设计模式 1、 模式(Pattern) 是较大的结构 组合与创新 達芬奇說&#xff1a;簡單是複雜的終極形式 (Simplicity is the ultimate form of sophistication) —Leonardo d…

vscode的keil assistant 中搜索不到全局变量

搜不到 但是在包含的文件中输入 ../../../,就是全局搜索的结果 我的文件结构是&#xff1a;\Desktop\LVGL文件系统移植&#xff08;lvgl8&#xff0e;&#xff13;&#xff09;\Projects\MDK-ARM 盲猜是keil assistant 当前文件夹打开的时候是进入到了MDK-ARM文件夹层次&…

HTML语法规范

HTML语法规则 HTML 标签是由尖括号包围的关键词&#xff0c;标签通常是成对出现的&#xff0c;例如 <html> 和 </html>&#xff0c;称为双标签 。标签对中的第一个标签是开始标签&#xff0c;第二个标签是结束标签单标签比较少&#xff0c;例如<br />&#x…

flink实现复杂kafka数据读取

接上文&#xff1a;一文说清flink从编码到部署上线 环境说明&#xff1a;MySQL&#xff1a;5.7&#xff1b;flink&#xff1a;1.14.0&#xff1b;hadoop&#xff1a;3.0.0&#xff1b;操作系统&#xff1a;CentOS 7.6&#xff1b;JDK&#xff1a;1.8.0_401。 常见的文章中&…

大模型微调---Prompt-tuning微调

目录 一、前言二、Prompt-tuning实战2.1、下载模型到本地2.2、加载模型与数据集2.3、处理数据2.4、Prompt-tuning微调2.5、训练参数配置2.6、开始训练 三、模型评估四、完整训练代码 一、前言 Prompt-tuning通过修改输入文本的提示&#xff08;Prompt&#xff09;来引导模型生…

如何使用 WebAssembly 扩展后端应用

1. WebAssembly 简介 随着互联网的发展&#xff0c;越来越多的应用借助 Javascript 转到了 Web 端&#xff0c;但人们也发现&#xff0c;随着移动互联网的兴起&#xff0c;需要把大量的应用迁移到手机端&#xff0c;随着手端的应用逻辑越来越复杂&#xff0c;Javascript 的解析…

python学习——洛谷P2010 [NOIP2016 普及组] 回文日期 三种方法

[NOIP2016 普及组] 回文日期 文章目录 [NOIP2016 普及组] 回文日期题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示方法一方法二方法三 题目背景 NOIP2016 普及组 T2 题目描述 在日常生活中&#xff0c;通过年、月、日这…

前端yarn工具打包时网络连接问题排查与解决

最近线上前端打包时提示 “There appears to be trouble with your network connection”&#xff0c;以此文档记录下排查过程。 前端打包方式 docker启动临时容器打包&#xff0c;命令如下 docker run --rm -w /app -v pwd:/app alpine-node-common:v16.20-pro sh -c "…