QQ登录

只需要一步,快速开始

APP扫码登录

只需要一步,快速开始

手机号码,快捷登录

泡泡马甲APP 更多内容请下载泡泡马甲手机客户端APP 立即下载 ×
查看: 213|回复: 0

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

[复制链接]

等级头衔

积分成就    金币 : 2802
   泡泡 : 1516
   精华 : 6
   在线时间 : 1243 小时
   最后登录 : 2024-4-29

丰功伟绩

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

联系方式
发表于 2023-9-27 10:38:09 | 显示全部楼层 |阅读模式
实际编程时,经常会写入到文件,如何快速的写入到文件呢?这里介绍两种常见的方法,当然实际业务场景中会有很多种方案。5 T1 ^+ @3 P+ W8 Y9 q
第一种常见的编程方案是使用缓冲区,在调用系统文件写入函数时实际上已经做了一层封装,当我们向文件中写入内容时实际上会先写入到缓冲区,缓冲区慢或者调用flush函数时会将缓冲区内容写入到存储。这样可以提升文件写入性能减少应用对磁盘的频繁写入。# u4 z* q' f1 R% }/ `* c
在编程时,我们也可以参照缓冲区的原理,在应用层进行处理,即定义一块私有内存,当写入文件内容达到了缓冲区大小时就进行文件写入。这样可以减少频繁的文件写入操作,提高写入性能。代码示例如下:
8 {4 c* K8 p$ @
  1. #include <iostream>
  2. #include <fstream>
  3. #include <vector>
  4. const int BUFFER_SIZE = 8192; // 缓冲区大小
  5. void writeToFile(const std::string& fileName, const std::vector<char>& data) {
  6.     std::ofstream file(fileName, std::ios::binary);
  7.     file.write(data.data(), data.size());
  8.     file.close();
  9. }
  10. int main() {
  11.     std::vector<char> buffer(BUFFER_SIZE, 'A'); // 填充缓冲区数据
  12.     std::string fileName = "largeFile.txt";
  13.     std::vector<char> data;
  14.     int fileSize = 1024 * 1024 * 100; // 100MB
  15.     int totalBufferSize = 0;
  16.     std::ofstream file(fileName, std::ios::binary);
  17.     while (totalBufferSize < fileSize) {
  18.         int bufferSize = std::min(fileSize - totalBufferSize, BUFFER_SIZE);
  19.         file.write(buffer.data(), bufferSize);
  20.         totalBufferSize += bufferSize;
  21.     }
  22.     file.close();
  23.     std::cout << "大文件写入完成" << std::endl;
  24.     return 0;
  25. }
上述示例代码中,我们创建了一个大小为100MB的大文件,使用大小为8192字节的缓冲区进行写入操作。每次将缓冲区的内容写入文件,直到达到指定的文件大小
6 D. Y  D5 _* J- U第二种常见的编程方案是使用内存映射,利用操作系统提供的内存映射文件(Memory-mapped File)功能,将文件映射到内存中进行写操作,可以更快地进行大文件写入。本文中使用Boost开源库编写实现,如下代码所示。这里主要使用了BOOST库中的Boost.Interprocess和MemoryMappedFiles库来实现内存映射文件的操作。
3 o$ G! y% y5 @7 A& n
  1. #include <iostream>
  2. #include <boost/interprocess/file_mapping.hpp>
  3. #include <boost/interprocess/mapped_region.hpp>
  4. int main() {
  5.     std::string fileName = "largeFile.txt";
  6.     std::size_t fileSize = 1024 * 1024 * 100; // 100MB
  7.    
  8.     boost::interprocess::file_mapping::remove(fileName.c_str()); // 删除已存在的文件
  9.    
  10.     // 创建新文件
  11.     boost::interprocess::file_mapping file(fileName.c_str(), boost::interprocess::read_write);
  12.     boost::interprocess::mapped_region region(file, boost::interprocess::read_write, 0, fileSize);
  13.    
  14.     // 在内存中操作文件内容
  15.     char* addr = static_cast<char*>(region.get_address());
  16.     std::fill_n(addr, fileSize, 'A'); // 填充文件内容为'A'
  17.    
  18.     std::cout << "大文件写入完成" << std::endl;
  19.    
  20.     return 0;
  21. }
上述示例使用Boost.Interprocess库创建一个大小为100MB的文件,并将文件映射到内存中。然后使用mapped_region对象的get_address函数获取文件内容的内存地址,可以直接在内存中进行操作。这种方式避免了频繁的磁盘IO操作,同时提高了大文件写入的效率。3 K) x$ s- }5 N
当然,使用C++实现大文件的快速写入和读取有很多种方案,具体哪一种需要参考具体的业务场景。如上面的缓冲区方式使用场景主要是文件顺序写入的业务,而内存映射则适用于将内存中的内容直接写入到文件中。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-4-30 09:41

Powered by paopaomj X3.4 © 2016-2024 sitemap

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