如何使用文件实现循环缓冲区? [英] How to implement a circular buffer using a file?

查看:172
本文介绍了如何使用文件实现循环缓冲区?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序(C程序)打开同一文件的两个文件句柄(一个写入,一个读取模式)。应用程序中的两个独立的线程从文件读取并写入文件。这工作正常
由于我的应用程序在有限的ram磁盘大小的嵌入式设备上运行,所以我想写入 FileHandle 以达到最大大小,并读取 FileHandle 像循环缓冲区一样遵循。从这个问题这应该工作。但是,一旦将$ code> fseek 写入 FileHandle 到文件开头, fread 返回错误。在 fseek 到文件开头时, EOF 会重置吗?如果是这样,应该使用哪个函数来使写入文件位置设置为0,而不会导致 EOF 重置。



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







  1. 基于@neodelphi,我使用管道这个工作。不过我的用户需要我写一个文件。我收到多个实时视频监控流的频道,需要存储到硬盘中,并且还可以读取解码并显示在显示器上。


  2. 感谢@Clement建议做ftell我修复了我的代码中的几个错误,并为读者包装作品,但是读取数据似乎是陈旧的数据,因为写入仍然是缓冲的,但读取器从硬盘读取过时的内容。由于性能考虑,我无法避免缓冲(我得到需要写入硬盘的32Mbps的实时数据)。我已经尝试过这样的事情,例如只有在写回包到读取包装之间的时间间隔中才能刷新写入,并且在读取包装后截断文件(ftruncate),但这并不能解决陈旧的数据问题。


  3. 我试图用乒乓球方式使用两个文件,看看是否解决了这个问题,但是想知道是否有更好的解决方案。



解决方案

你应该有这样的东西:

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

//读取(假设二进制)
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



此外,只有确认数据已被写入时,您才可以阅读。但我猜你已经这样做了。


My application (C program) opens two file handles to the same file (one in write and one in read mode). Two separate threads in the app read from and write to the file. This works fine. Since my app runs on embedded device with a limited ram disk size, I would like write FileHandle to wrap to beginning of file on reaching max size and the read FileHandle to follow like a circular buffer. I understand from answers to this question that this should work. However as soon as I do fseek of write FileHandle to beginning of file, fread returns error. Will the EOF get reset on doing fseek to beginning of file? If so, which function should be used to cause write file position to get set to 0 without causing EOF to be reset.

EDIT/UPDATE: I tried couple of things:


  1. Based on @neodelphi I used pipes this works. However my usecase requires I write to a file. I receive multiple channels of live video surveilance stream that needs to be stored to harddisk and also read back decoded and displayed on monitor.

  2. Thanks to @Clement suggestions on doing ftell I fixed a couple of bugs in my code and wrap works for the reader however, the data read appears to be stale data since write are still buffered but reader reads stale content from hard disk. I cant avoid buffering due to performance considerations (I get 32Mbps of live data that needs to be written to harddisk). I have tried things like flushing writes only in the interval from when write wraps to when read wraps and truncating the file (ftruncate) after read wraps but this doesnt solve the stale data problem.

  3. I am trying to use two files in ping-pong fashion to see if this solves the issue but want to know if there is a better solution

解决方案

You should have something like that :

// 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 !
}

Not tested, but it gives an idea. The write should also handle the case BUFFER_MAX is not modulo WRITE_CHUNK_SIZE.

Also, you may read only if you are sure that the data has already been written. But I guess you already do that.

这篇关于如何使用文件实现循环缓冲区?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆