C语言实现将内存中的内容实时保存。

jbsxhwh 2017-10-25 10:07:25
使用C语言开发一个数据采集程序。数据每秒1000次采集,数据可以实现实时同步到内存中,问题是如何保存到硬盘上。
每个原始数据为512*512的一个矩阵。如果进行基线检查(每个矩阵元减去一个背景值),那么数据为一个大概1000-2000个点的稀疏矩阵。如果不进行基线检查,就是原始矩阵512*512个点。

如果要实现数据的实时保存,请问采用什么方法比较好?非常感谢!下面是我用的方法,但是发现耗时严重每秒大概2次不到的样子。CPU:intel i5-6500@3.2GHz,16GB内存。

for (int jj=0;jj<1000;jj++) {
char* filename;
filename = char(jj);
FILE *f = fopen( filename, "w" );
for (y=0; y<ny; y++) {
float *ptr = (float*)GetPtr(bufnum,y);
for (x=0; x<nx; x++, ptr++)
fprintf(f,"%*.3f ",12, *ptr);
fprintf(f,"\n");
}

}
fclose(f);
...全文
663 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
JasonHuo_ 2017-10-28
  • 打赏
  • 举报
回复
你代码本身就存在问题,你打开了多次fopen,如果你想向一个文件中紧接文件尾部继续写入可以用fflush
codedoctor 2017-10-26
  • 打赏
  • 举报
回复
内存中的数据只要你程序没有崩溃或者关闭,就会一直存在,所以你要做的,就是写一个好的、鲁棒的程序,保证其稳定性,
codedoctor 2017-10-26
  • 打赏
  • 举报
回复
嗯。。稀疏矩阵最好用位图bitmap,可以去自己参考一下思想。空间利用率和CPU利用率都很高 如果想进一步压缩时间的话,最好减少IO的操作次数,考虑把成堆数据一次性输出到文件中 最后,将数据从内存中输出到硬盘中的操作,是不怎么会用到CPU的,电脑自带存储管理管线和控制器,CPU只是吧数据放在控制器上而已,传输操作不归CPU管
jbsxhwh 2017-10-25
  • 打赏
  • 举报
回复
由于C语言不能获得足够的权限,C程序是做成dll文件被其他程序调用使用的。不知道下面这个替代方法是否可行。 1,指定一个较大的内存区域,用于不停的存储新来的数据。 2. 主程序每调用一次C程序(dll文件),就在内存中进行一次基线检查,然后将剩下的矩阵元(1000个点)写入1中开辟的内存中。 并保证内存空间中的数据不消失(怎么保证?) 3.多次采集后例如(10万次后,将内存中的数据一次性写入硬盘) 由于每次主程序调用的是dll文件,每次调用完之后,dll文件都关闭了,那怎么保证内存空间中的数据不消失? 非常谢谢!
jbsxhwh 2017-10-25
  • 打赏
  • 举报
回复
谢谢大家回复,重新编辑了一下. 因为数据量比较大,担心CPU运行不过来,所以打算每次都把数据保存下来,保存到不到的文件中。 for (int jj=0;jj<1000;jj++) // 采集1000次 { char* filename; //每一次的文件名 filename = char(jj);//每一次的文件名 FILE *f = fopen( filename, "w" ); //每次保存一个新文件 for (y=0; y<ny; y++) { float *ptr = (float*)GetPtr(bufnum,y); for (x=0; x<nx; x++, ptr++) fprintf(f,"%*.3f ",12, *ptr); //把数据写入新文件 fprintf(f,"\n"); } fclose(f); //数据采集完一次,关闭文件; }
自信男孩 2017-10-25
  • 打赏
  • 举报
回复
打开文件会比较耗时,所以若是循环打开或者打开多个文件耗时就更多了。
自信男孩 2017-10-25
  • 打赏
  • 举报
回复
你的文件打开次数太多了吧
for (int jj=0;jj<1000;jj++) {
char* filename;
    filename = char(jj);
      FILE *f = fopen( filename, "w" );
      for (y=0; y<ny; y++) {
         float *ptr = (float*)GetPtr(bufnum,y);
         for (x=0; x<nx; x++, ptr++)
            fprintf(f,"%*.3f ",12, *ptr);
         fprintf(f,"\n");
      }
   
}   
你要打开几个文件?看你的打开文件在一个循环里,那么应该是打开多次(或打开多个文件)。如果实时保存时,只需要保存一份数据,建议先把文件打开再循环写入。另外,再次写入时将文件指针,只需要将文件指针重新指向文件开头即可。使用fseek或者rewind都可以实现将文件指针指向文件开始位置
老马何以识途 2017-10-25
  • 打赏
  • 举报
回复
你这代码本身就有问题啊,在循环体里边执行fopen,却在循环体外边fclose,没有配对。fopen应该在循环之前做。
赵4老师 2017-10-25
  • 打赏
  • 举报
回复
// 创建文件句柄
HANDLE hFile = ::CreateFile(lpszFileName, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// 创建文件映射
HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_COMMIT, NULL, NULL, NULL);
// 读取映射中的内存
LPVOID lpBuffer = ::MapViewOfFile(hMap, FILE_MAP_READ, NULL, NULL, NULL);

// 好了文件的内存已经获取了,你可以随意处理了

// 释放映射内存
::UnmapViewOfFile(lpBuffer);
// 关闭文件映射
::CloseHandle(hMap);
// close file handle
::CloseHandle(hFile);
赵4老师 2017-10-25
  • 打赏
  • 举报
回复
// 创建文件句柄 HANDLE hFile = ::CreateFile(lpszFileName, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // 创建文件映射 HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_COMMIT, NULL, NULL, NULL); // 读取映射中的内存 LPVOID lpBuffer = ::MapViewOfFile(hMap, FILE_MAP_READ, NULL, NULL, NULL); // 好了文件的内存已经获取了,你可以随意处理了 // 释放映射内存 ::UnmapViewOfFile(lpBuffer); // 关闭文件映射 ::CloseHandle(hMap); // close file handle ::CloseHandle(hFile);

69,340

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧