用C++快速编写许多大文件
Writing many large files quickly in C++
我有一个程序,它从不同的相机获取原始数据流并将其写入磁盘。该程序运行此类录制约2分钟,然后使用另一个程序来处理帧。
每个原始帧为2MB,帧速率为30fps(即数据速率约为60MB/s),我正在写入一个SSD,它可以轻松处理持续的>150MB/s(通过从另一个磁盘复制4000个2MB文件进行测试,耗时38秒,Process Explorer显示持续的IO活动)。
我的问题是,偶尔对fopen()
、fwrite()
和fclose()
的调用会停滞长达5秒,这意味着300MB的帧会作为备份日志在内存中积累起来,在其中一些延迟之后,我达到了32位进程的4GB限制。(当延迟发生时,Process Explorer显示IO活动存在缺口)
有一个线程为添加到队列中的每个新帧运行一个调用此函数的循环:
writeFrame(char* data, size_t dataSize, char* filepath)
{
// Time block 2
FILE* pFile = NULL;
fopen(&pFile, filepath, "wb");
// End Time block 2
// Time block 3
fwrite(data,1,dataSize,pFile);
// End Time block 3
// Time block 4
fclose(pFile);
// End Time block 4
}
(实际代码中也有错误检查,但这对这个问题没有影响)我记录了每个块所需的时间和运行函数所需的总时间,我得到的结果大部分时间看起来是这样的:(时间以毫秒为单位)
TotalT,5, FOpenT,1, FWriteT,2, FCloseT,2
TotalT,4, FOpenT,1, FWriteT,1, FCloseT,2
TotalT,5, FOpenT,1, FWriteT,2, FCloseT,2
即~5ms运行整个函数,~1ms打开文件,~2ms调用write,~2ms关闭文件。
然而,偶尔(平均每50帧中有1帧,但有时这个问题发生之间可能有数千帧),我会得到超过4000ms的帧:
TotalT,4032, FOpenT,4023, FWriteT,6, FCloseT,3
和
TotalT,1533, FOpenT,1, FWriteT,2, FCloseT,1530
所有的帧都是相同的大小,并且它从不占用额外时间的fwrite
,总是fopen
或fclose
没有其他进程正在对此SSD进行读/写操作(通过进程监视器确认)。
有人知道是什么导致了这个问题和/或任何避免/减轻这个问题的方法吗?
我站在X.J.一边,您可能在一个目录中写入了太多文件。解决方案可以是为每批帧创建一个新目录。还可以考虑在创建文件后直接调用SetEndOfFile
,因为这将帮助Windows在单个操作中分配足够的空间。
FAT并不是一个真正的解决方案,因为它在大目录上做得更糟。
准备空文件(2 MB的文件用零填充),使空间已经"准备好",然后覆盖这些文件。或者创建一个由多个帧组成的文件,这样可以减少文件数量。
有一些库可以对视频进行压缩、解压缩和播放:
libTheora可能很有用,因为它已经压缩了帧(好吧,你需要在一个文件中输出视频),而且速度很快(顺便说一句,有损压缩)。
- 在c++中获取大文件的大小
- 加密++验证大文件签名
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?
- 比较两个没有一行共同点的大文件
- 通过boost asio iostream下载大文件的最快方法是什么?
- C++读取大文件并将其保存到字符串中,然后删除特定的随机单词
- 程序应该显示文件的最后5行,但它不适用于大文件
- 多部分/表单数据丢失大文件的字节
- LZMA c++ 压缩大文件的问题
- 上传大文件并解析时使用 Node.js v10.15.1 时出现致命错误
- C++如何附加ifstream以将多个文件读取为一个大文件
- c++ - 将大文件记录处理到 cpp 容器的最有效方法
- 将大文件读取到字符数组的正确方法
- 阅读一个大文件来计算重复K次的单词数
- 使用 c++ 对大文件的 SSD 读取
- 文件 read() 挂在二进制大文件上
- 如何快速保存大文件中的小更改
- 提升::async_write大文件和内存消耗
- 如何加快正则表达式搜索C++中大量潜在的大文件?
- 用C++快速编写许多大文件