【问题标题】:How to implement a circular buffer using a file?如何使用文件实现循环缓冲区?
【发布时间】:2011-08-29 14:34:59
【问题描述】:

我的应用程序(C 程序)打开同一个文件的两个文件句柄(一个处于写入模式,一个处于读取模式)。应用程序中的两个独立线程读取和写入文件。这工作正常。 由于我的应用程序在具有有限 RAM 磁盘大小的嵌入式设备上运行,我想写入 FileHandle 以在达到最大大小时换行到文件的开头,并像循环缓冲区一样读取 FileHandle。我从对this question 的回答中了解到这应该可行。但是,一旦我将FileHandle 写入文件开头的fseekfread 就会返回错误。 EOF 会在将fseek 重置为文件开头吗?如果是这样,应该使用哪个函数将写入文件位置设置为 0 而不会导致 EOF 被重置。

编辑/更新: 我尝试了几件事:


  1. 基于@neodelphi,我使用了管道。但是我的用例需要我写入文件。我收到了多个通道的实时视频监控流,需要将其存储到硬盘上,并且还需要回读解码并显示在监视器上。

  2. 1234563硬盘。由于性能考虑,我无法避免缓冲(我得到 32Mbps 的需要写入硬盘的实时数据)。我已经尝试过诸如仅在从写入换行到读取换行的时间间隔内刷新写入以及在读取换行后截断文件(ftruncate)之类的方法,但这并不能解决陈旧数据问题。
  3. 我正在尝试以 ping-pong 方式使用两个文件,看看这是否能解决问题,但想知道是否有更好的解决方案

【问题讨论】:

  • 你在读写文件时锁定了吗?
  • 如果您在类似 linux 的系统上进行开发,您是否尝试过管道文件?这类文件只存储已写入但未读取的内容,因此可能不需要实现循环缓冲区。
  • @Clement。我没有任何锁。我使用 std C lib fread 和 fwrite 调用
  • 如果你在同一个文件句柄上使用它们,会有麻烦。是这样吗?
  • 根据cim.mcgill.ca/~franco/OpSys-304-427/lecture-notes/node27.html ,在不同模式下打开的两个文件句柄位置之间应该没有影响(至少在UNIX系统上)。你能发布一些可运行的代码吗?也许这是一个小的逻辑错误。

标签: c file-io embedded


【解决方案1】:

你应该有类似的东西:

// Write
if(ftell(WriteHandle)>BUFFER_MAX) rewind (WriteHandle);
fwrite(WriteHandle,/* ... */);

// Read (assuming binary)
readSize = fread (buffer,1,READ_CHUNK_SIZE,ReadHandle);
if(readSize!=READ_CHUNK_SIZE){
    rewind (ReadHandle);
    if(fread (buffer+readSize,1,READ_CHUNK_SIZE-readSize,ReadHandle)!=READ_CHUNK_SIZE-readSize)
        ;// ERROR !
}

未经测试,但它提供了一个想法。写入还应处理BUFFER_MAX 不是模WRITE_CHUNK_SIZE 的情况。

此外,您只能在确定数据已写入时才能读取。但我猜你已经这样做了。

【讨论】:

  • 下面是我的代码。与您所拥有的类似,除了我使用 fseek 而不是倒带。` fpos = ftell(fp);if ((fpos + bytesToWrite) >= maxFileSize){fseek(fp,0,SEEK_SET);} `
  • @Bardi fread 不只是返回错误,它返回一个数字。什么号码 ? feof() 返回什么?此外,feof() 在 fseek、rewind 和 clearerr (cplusplus.com/reference/clibrary/cstdio/clearerr) 时重置。
  • 在写换行时,我将换行位置设置在共享变量中(具有互斥保护)。当读取位置到达此换行位置时,我什至在执行 fread 之前都会倒带读取文件句柄。所以我希望不会发生错误。即使读取位置尚未达到回绕点,一旦写入回绕,我也会收到 fread 错误。读取将始终与我的应用程序中的写入块大小相同
  • 您能否尝试对读取失败进行说明?这可能有助于发现问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-17
  • 2010-10-24
  • 2014-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多