2011-08-25 5 views
6

Mon application (programme C) ouvre deux handles de fichiers dans le même fichier (un en écriture et un en lecture). Deux threads distincts dans l'application lisent et écrivent dans le fichier. Cela fonctionne bien. Depuis mon application fonctionne sur un périphérique embarqué avec une taille de disque ram limitée, je voudrais écrire FileHandle pour enrouler au début du fichier sur atteindre la taille maximale et la lire FileHandle à suivre comme un tampon circulaire. Je comprends des réponses à this question que ceci devrait fonctionner. Cependant, dès que je fais fseek d'écrire FileHandle au début du fichier, fread renvoie une erreur. Est-ce que le EOF sera réinitialisé en faisant fseek au début du fichier? Si c'est le cas, quelle fonction doit être utilisée pour que la position du fichier d'écriture soit mise à 0 sans réinitialiser EOF.Comment implémenter un tampon circulaire en utilisant un fichier?

EDIT/MISE À JOUR: j'ai essayé deux choses:


  1. Basé sur @neodelphi je tuyaux cela fonctionne. Cependant, mon utilisation nécessite que j'écris dans un fichier. Je reçois plusieurs canaux de flux de vidéosurveillance en direct qui doivent être stockés sur le disque dur et également relus décodés et affichés sur le moniteur. Grâce aux suggestions de @Clement sur ftell j'ai corrigé quelques bogues dans mon code et les travaux de retour pour le lecteur cependant, les données lues semblent être des données périmées puisque l'écriture est encore mise en mémoire tampon mais le lecteur lit le contenu périmé de dur disque. Je ne peux pas éviter la mise en mémoire tampon en raison de considérations de performance (j'obtiens 32 Mbps de données en direct qui doivent être écrites sur le disque dur). J'ai essayé des choses comme des écritures de vidage seulement dans l'intervalle de quand l'enveloppe enveloppe à quand la lecture enveloppe et tronque le fichier (ftruncate) après la lecture enveloppe mais ceci ne résout pas le problème de données périmé.

  2. Je suis en train d'utiliser deux fichiers dans la mode ping-pong pour voir si cela résout le problème, mais je veux savoir s'il y a une meilleure solution

+0

Verrouillez-vous en lisant le fichier? –

+1

Si vous développez sur un système de type Linux, avez-vous essayé les fichiers de tuyaux? Ces types de fichiers ne stockent que ce qui a été écrit mais pas lu, donc l'implémentation d'un tampon circulaire peut ne pas être nécessaire. – neodelphi

+0

@Clement. Je n'ai pas de verrous. J'utilise std C lib fread et fwrite – Badri

Répondre

1

Vous devriez avoir quelque chose comme ça:

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

Non testé, mais il donne une idée. L'écriture doit également gérer le cas BUFFER_MAX n'est pas modulo WRITE_CHUNK_SIZE.

En outre, vous pouvez lire uniquement si vous êtes sûr que les données ont déjà été écrites. Mais je suppose que tu le fais déjà.

+0

Voici mon code. Similaire à ce que vous avez, sauf que j'utilise fseek au lieu de rewind. »Fpos = ftell (fp); si ((fpos + bytesToWrite)> = maxFileSize) {fseek (fp, 0, SEEK_SET);}' – Badri

+0

@Bardi fread don ' t juste retourner l'erreur, il renvoie un nombre. Quel nombre ? Que retourne feof() '? De même, 'feof()' est réinitialisé sur fseek, rewind et clearerr (http://www.cplusplus.com/reference/clibrary/cstdio/clearerr/). –

+0

Lors d'un retour en écriture, je règle la position de retour à la ligne dans une variable partagée (avec protection mutex). Lorsque la position de lecture atteint cette position d'enroulement, je rembobine Read File Handle avant même de faire la fread. Donc, je ne m'attends à aucune erreur. Je reçois des erreurs de fread dès que l'écriture est enroulée même si la position de lecture n'a pas encore atteint le point de bouclage. La lecture sera toujours de la même taille que la taille de bloc d'écriture dans mon application – Badri

Questions connexes