2011-08-25 83 views
6

我的应用程序(C程序)打开两个文件句柄到相同的文件(一个在写入,一个在读取模式)。应用程序中的两个独立线程读取和写入文件。这工作正常。 因为我的应用程序具有有限的RAM磁盘大小的嵌入式设备上运行,我想写FileHandle包文件的开头部分就达到最大尺寸和阅读FileHandle遵循类似的循环缓冲区。我从对this question的回答中了解到这应该起作用。但是只要我做的fseekFileHandle文件的开头,fread返回错误。将EOF复位到fseek开始文件?如果是这样,应该使用哪个函数来使写入文件位置被设置为0,而不会导致EOF被重置。如何使用文件实现循环缓冲区?

编辑/ UPDATE: 我试过几件事情:


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

  2. 感谢@Clement关于做fll的建议我在代码中修复了一些bug,并为阅读器打包工作,但是,由于写入仍然被缓存,读取的数据似乎是陈旧的数据,但读取器从硬盘读取陈旧的内容磁盘。由于性能方面的考虑,我不能避免缓冲(我得到需要写入硬盘的32Mbps的实时数据)。我只尝试了在写封装到读封装之间的时间间隔以及在读封装后截断文件(ftruncate)的时间间隔内刷新写入的事情,但这并不能解决陈旧的数据问题。

  3. 我试图使用乒乓时尚的两个文件,看看是否能解决问题,但想知道是否有更好的解决办法

+0

你是否锁定,而读写文件? –

+1

如果您正在开发一个类似linux的系统,您是否尝试过使用管道文件?这些类型的文件只存储已写入但未读取的内容,因此可能不需要实现循环缓冲区。 – neodelphi

+0

@Clement。我没有任何锁。我使用std C lib fread和fwrite调用 – Badri

回答

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

另外,如果你确信该数据已被写入可能只读。但我想你已经这样做了。

+0

下面是我的代码。 fpos = ftell(fp); if((fpos + bytesToWrite)> = maxFileSize){fseek(fp,0,SEEK_SET);}' – Badri

+0

@Bardi fread don'只是返回错误,它返回一个数字。什么号码 ? 'feof()'返回什么?另外,'feof()'在fseek,rewind和clearerr上重置(http://www.cplusplus.com/reference/clibrary/cstdio/clearerr/)。 –

+0

在写包装上,我将包装位置设置为共享变量(具有互斥锁保护)。当读取位置到达此位置时,即使在执行fread之前,我也会读取文件句柄。所以我希望没有错误发生。即使读取位置还没有达到包装点,写入时仍会发生fread错误。在我的应用程序中,读取的大小始终与写入块大小的大小相同 – Badri