Как реализовать кольцевой буфер, используя файл? - PullRequest
6 голосов
/ 25 августа 2011

Мое приложение (программа C) открывает два дескриптора файла для одного и того же файла (один в режиме записи и один в режиме чтения).Два отдельных потока в приложении читают и записывают в файл.Это отлично работает.Поскольку мое приложение работает на встроенном устройстве с ограниченным объемом оперативной памяти, я хотел бы написать FileHandle для переноса в начало файла при достижении максимального размера, а чтение FileHandle должно следовать за круглым буфером.Из ответов на этот вопрос я понимаю, что это должно работать.Однако, как только я fseek записываю FileHandle в начало файла, fread возвращает ошибку.Будет ли EOF сброшен при выполнении fseek до начала файла?Если это так, то какую функцию следует использовать для установки позиции записи файла в 0 без сброса EOF.

РЕДАКТИРОВАНИЕ / ОБНОВЛЕНИЕ: Я пробовал несколько вещей:


  1. На основании @neodelphi я использовал трубы, это работает.Однако мой вариант использования требует, чтобы я записал в файл.Я получаю несколько каналов потока видеонаблюдения в режиме реального времени, который необходимо сохранить на жесткий диск, а также прочитать обратно, декодировать и отобразить на мониторе.

  2. Благодаря предложениям @Clement по выполнению, я исправил паруошибок в моем коде и переносе работает для читателя, однако считанные данные выглядят устаревшими, поскольку запись все еще буферизируется, но читатель считывает устаревший контент с жесткого диска.Я не могу избежать буферизации из-за соображений производительности (я получаю 32 Мбит / с живых данных, которые нужно записать на жесткий диск).Я пробовал такие вещи, как очистка записи только в промежутке времени между переносами записи и переносами чтения и усечением файла (ftruncate) после переносов чтения, но это не решает проблему устаревших данных.

  3. Я пытаюсь использовать два файла в стиле пинг-понг, чтобы увидеть, решит ли это проблему, но хочу знать, есть ли лучшее решение

1 Ответ

1 голос
/ 25 августа 2011

У вас должно быть что-то подобное:

// 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.

Кроме того, вы можете читать только в том случае, если уверены, что данные уже записаны. Но я думаю, вы уже это делаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...