QQ登录

只需要一步,快速开始

APP扫码登录

只需要一步,快速开始

手机号码,快捷登录

手机号码,快捷登录

查看: 367|回复: 0

[C/C++/Qt] 正确使用C++快速写入大文件

[复制链接]

等级头衔

积分成就    金币 : 2851
   泡泡 : 1516
   精华 : 6
   在线时间 : 1305 小时
   最后登录 : 2024-12-7

丰功伟绩

优秀达人突出贡献荣誉管理论坛元老活跃会员

联系方式
发表于 2023-9-27 10:38:09 | 显示全部楼层 |阅读模式
实际编程时,经常会写入到文件,如何快速的写入到文件呢?这里介绍两种常见的方法,当然实际业务场景中会有很多种方案。
3 D( k! u+ @! D! p第一种常见的编程方案是使用缓冲区,在调用系统文件写入函数时实际上已经做了一层封装,当我们向文件中写入内容时实际上会先写入到缓冲区,缓冲区慢或者调用flush函数时会将缓冲区内容写入到存储。这样可以提升文件写入性能减少应用对磁盘的频繁写入。- o& J1 v# Y. `" Q* V; j) O
在编程时,我们也可以参照缓冲区的原理,在应用层进行处理,即定义一块私有内存,当写入文件内容达到了缓冲区大小时就进行文件写入。这样可以减少频繁的文件写入操作,提高写入性能。代码示例如下:7 D. O0 Q% }4 V3 k- Q% J
#include <iostream>
#include <fstream>
#include <vector>

const int BUFFER_SIZE = 8192; // 缓冲区大小

void writeToFile(const std::string& fileName, const std::vector<char>& data) {
    std::ofstream file(fileName, std::ios::binary);
    file.write(data.data(), data.size());
    file.close();
}

int main() {
    std::vector<char> buffer(BUFFER_SIZE, 'A'); // 填充缓冲区数据

    std::string fileName = "largeFile.txt";
    std::vector<char> data;

    int fileSize = 1024 * 1024 * 100; // 100MB
    int totalBufferSize = 0;

    std::ofstream file(fileName, std::ios::binary);

    while (totalBufferSize < fileSize) {
        int bufferSize = std::min(fileSize - totalBufferSize, BUFFER_SIZE);
        file.write(buffer.data(), bufferSize);
        totalBufferSize += bufferSize;
    }

    file.close();
    std::cout << "大文件写入完成" << std::endl;
    return 0;
}
上述示例代码中,我们创建了一个大小为100MB的大文件,使用大小为8192字节的缓冲区进行写入操作。每次将缓冲区的内容写入文件,直到达到指定的文件大小# Y2 g* V' L  ?8 G4 J: L1 `0 k
第二种常见的编程方案是使用内存映射,利用操作系统提供的内存映射文件(Memory-mapped File)功能,将文件映射到内存中进行写操作,可以更快地进行大文件写入。本文中使用Boost开源库编写实现,如下代码所示。这里主要使用了BOOST库中的Boost.Interprocess和MemoryMappedFiles库来实现内存映射文件的操作。
) b- ^0 c$ A- D
#include <iostream>
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>

int main() {
    std::string fileName = "largeFile.txt";
    std::size_t fileSize = 1024 * 1024 * 100; // 100MB
    
    boost::interprocess::file_mapping::remove(fileName.c_str()); // 删除已存在的文件
    
    // 创建新文件
    boost::interprocess::file_mapping file(fileName.c_str(), boost::interprocess::read_write);
    boost::interprocess::mapped_region region(file, boost::interprocess::read_write, 0, fileSize);
    
    // 在内存中操作文件内容
    char* addr = static_cast<char*>(region.get_address());
    std::fill_n(addr, fileSize, 'A'); // 填充文件内容为'A'
    
    std::cout << "大文件写入完成" << std::endl;
    
    return 0;
}
上述示例使用Boost.Interprocess库创建一个大小为100MB的文件,并将文件映射到内存中。然后使用mapped_region对象的get_address函数获取文件内容的内存地址,可以直接在内存中进行操作。这种方式避免了频繁的磁盘IO操作,同时提高了大文件写入的效率。
, p. k( n) m6 E5 M当然,使用C++实现大文件的快速写入和读取有很多种方案,具体哪一种需要参考具体的业务场景。如上面的缓冲区方式使用场景主要是文件顺序写入的业务,而内存映射则适用于将内存中的内容直接写入到文件中。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|paopaomj.COM ( 渝ICP备18007172号|渝公网安备50010502503914号 )

GMT+8, 2024-12-7 04:13

Powered by paopaomj X3.5 © 2016-2025 sitemap

快速回复 返回顶部 返回列表