Écrire une circulaire de fichier en c++
J'ai besoin d'écrire une circulaire de fichier en c++. Le programme a pour écrire des lignes dans un fichier et quand le code atteint un nombre maximal de lignes, il faut remplacer les lignes au début du fichier.
Quelqu'un a une idée?
pourquoi avez-vous besoin pour mettre en œuvre cette? ce qu'est le vrai problème essayez-vous de résoudre?
J'ai besoin d'écrire des listes d'identifiants dans un fichier. Chaque liste en une seule ligne. Mais pas au-delà d'un nombre maximum de lignes. À perdre la plus ancienne. Une autre solution possible serait de créer un windowfile. Donc... Supprimer la première ligne et ajouter la nouvelle ligne à la fin. Vous savez comment faire pour supprimer la première ligne d'un fichier?
Désolé, vous n'avez toujours pas dit ce que le problème que vous essayez de résoudre est - que vous avez décrit un possible (et à mon avis mauvaise) solution.
Le fichier est-il nécessaire d'un fichier texte? Est une ligne fixe longueur faisable?
Le fichier est nécessaire parce qu'elle est l'entrée d'une autre application.
J'ai besoin d'écrire des listes d'identifiants dans un fichier. Chaque liste en une seule ligne. Mais pas au-delà d'un nombre maximum de lignes. À perdre la plus ancienne. Une autre solution possible serait de créer un windowfile. Donc... Supprimer la première ligne et ajouter la nouvelle ligne à la fin. Vous savez comment faire pour supprimer la première ligne d'un fichier?
Désolé, vous n'avez toujours pas dit ce que le problème que vous essayez de résoudre est - que vous avez décrit un possible (et à mon avis mauvaise) solution.
Le fichier est-il nécessaire d'un fichier texte? Est une ligne fixe longueur faisable?
Le fichier est nécessaire parce qu'elle est l'entrée d'une autre application.
OriginalL'auteur Kram | 2009-05-20
Vous devez vous connecter pour publier un commentaire.
Malheureusement, vous ne pouvez pas tronquer/remplacer les lignes au début d'un fichier sans avoir à réécrire l'ensemble de la chose.
Nouvelle Suggestion
J'ai juste pensé à une nouvelle approche qui pourrait faire l'affaire pour vous...
Vous pourriez inclure un petit en-tête de votre fichier a la structure suivante.
Edit: de la Foutaise, j'ai juste décrit une variante d'un tampon circulaire!
Champs D'En-Tête
Bytes 00 - 07 (long)
- Total (en cours) nombre de lignes écrites dans le fichier.Bytes 08 - 15 (long)
- Pointeur vers le début de la "réelle" de la première ligne de votre fichier. Ce sera d'abord l'octet de l'en-tête se termine, mais va changer plus tard lorsque des données sont écrasées.`Bytes 16 - 23 (long)
- Longueur de la "fin de l'article" du fichier. Encore une fois, ce sera d'abord de zéro, mais il va changer plus tard lorsque des données sont écrasées.Lire Algorithme (En Pseudo-Code)
Lit l'intégralité du fichier.
Écrire L'Algorithme (En Pseudo-Code)
Écrit un nombre arbitraire de nouvelles lignes dans le fichier.
Pas très simple algorith, je reconnais! Je pense néanmoins qu'il est tout à fait élégante, en quelque sorte. Laissez-moi savoir si ce n'est pas évident, bien sûr. J'espère que ça doit faire précisément ce que vous voulez maintenant.
Suggestion
Maintenant, si vous êtes à la lignes sont garantis être de longueur constante (en octets), vous pourriez facilement vous suffit demander retour à l'idéal point et d'écraser les données existantes. Cela semblerait plutôt une situation peu probable cependant. Si vous n'avez pas l'esprit en imposant la restriction que vos lignes doivent avoir une longueur maximale, et en plus de rembourrage chacune des lignes que vous écrivez à cette longueur maximale, alors cela pourrait rendre les choses faciles pour vous. Pourtant, il a ses inconvénients comme augmentant considérablement la taille du fichier dans certaines circonstances (c'est à dire la plupart des lignes sont beaucoup court-circuité de la longueur maximale.) Tout dépend de la situation si cela est acceptable ou pas...
Enfin, vous aurez envie de regarder en utilisant un existant système d'enregistrement, en fonction de votre objectif précis.
Pas de problème. 🙂 Voir mon jour de réponse pour une autre méthode.
Si vous avez utilisé fixe la taille des lignes (par exemple, 80 octets/ligne) vous pouvez fichier = fopen(...,"rb+") et puis fseek(fichier,line_no*80,SEEK_SET), suivie par certains memcpy/strcpy/etc et puis fwrite(charbuffer,80,fichier).
OriginalL'auteur Noldorin
La façon habituelle de gérer les logs qui n'explose pas dans la taille est d'utiliser rolling fichiers journaux, puis les rouler une fois par jour ou similaire, et de ne garder que les N fichiers les plus récents.
Par exemple, chaque jour, vous pouvez créer un nouveau fichier de log avec le nom " application_2009_05_20.le journal', et de commencer à écrire, toujours en ajoutant.
Une fois que vous avez 14 jours d'une valeur de fichiers de log, vous commencez à supprimer les plus anciennes.
OriginalL'auteur Lasse Vågsæther Karlsen
Car les fichiers sont octet, et vous avez besoin d'une ligne orientée service, vous avez deux choix:
mettre en œuvre une ligne orientée wrapper autour du fichier
passer à une ligne orientée de l'appareil. Juste le haut de mon esprit: SQLite a quelques belles C++ wrappers disponibles.
OriginalL'auteur xtofl
L'utilisation d'un tampon circulaire et écrire le contenu du buffer dans un fichier pour chaque ajout.
Voici un petit code simple taille de la solution. C'est un simple tampon circulaire de chaînes et chaque fois que vous ajoutez des chaînes qu'il écrit l'intégralité de la mémoire tampon de chaînes de caractères dans le fichier (bien sûr, vous encourez une significative coût pour l'écriture tous les cordes pour une seule opération d'ajout. Donc c'est seulement pour un petit nombre de chaînes de caractères).
Simple de mise en œuvre de la circulaire du tampon avec la sortie vers un fichier:
Ainsi, dans l'exemple ci-dessus nous avons eu 5 lignes d'entrée et de notre mémoire tampon n'était que de 4 lignes de long. Par conséquent, la sortie devrait avoir 4 lignes et la première ligne doit être remplacée par la dernière ligne de "Goodbye world". Bien sûr la première ligne de la sortie confirme n'avoir "Goodbye world":
OriginalL'auteur Trevor Boyd Smith
Solution Simple:
Cette solution est conçue pour offrir une constante de la longueur du fichier, plutôt que d'un constant nombre de lignes dans le fichier. Le nombre de lignes varie au fil du temps en fonction de la longueur. Cette solution rend plus difficile de demander à des numéros de ligne spécifiques rapidement, si vous pouviez mettre quelques données sur l'indicateur en haut ou en bas du fichier à rendre cela plus facile.
"Intelligent" de la Solution (variation de la solution ci-dessus):
Suffit d'utiliser la même astuce qui est parfois utilisée pour les deques. Juste expicitely enrouler autour depuis le début du fichier jusqu'à la fin, mais de garder une trace de l'endroit au début/à la fin du fichier est. Vous pourriez écrire une déballer utilitaire pour convertir ce fichier à un standard quand vous avez voulu le lire avec un programme qui ne le supporte pas. Cette solution est VRAIMENT facile à mettre en œuvre, mais j'aime bien la version ci-dessus mieux.
Laid Solution:
Lors de l'ajout de lignes, ajouter une quantité modérée de rembourrage pour chaque ligne que vous ajoutez.
Chaque fois que vous souhaitez ajouter une nouvelle ligne, procédez comme suit:
Noter que cela fonctionne assez mal, à moins que vos lignes sont assez cohérente sur la durée. Une solution plus simple est de garantir les lignes sont de longueur constante (mais mis dans un moyen de créer des multi-lignes "les lignes" dans le cas où vous dépassez cette durée.
OriginalL'auteur Brian
si les fichiers doivent être des fichiers texte:
Ceci est très problématique avec différentes longueurs de ligne. Vos deux premières lignes de 80 caractères, comment voulez-vous écraser avec un 100 ligne de caractère?
Si la nouvelle ligne devrait remplacer la première ligne, cela aurait pour conséquence une insertion de fichier, qui est une opération très coûteuse (en gros, le reste du fichier doit être lu et écrit). Vous ne voulez vraiment pas à le faire pour tous, mais un minimum de quantités de données.
Si c'est pour l'enregistrement de l'objet, l'usage rollng fichiers journaux - par exemple, un jour (comme suggéré par lassevek).
Je l'ai fait encore plus simple: lorsque la taille du fichier dépasse une limite, l'ancien fichier est renommé .bak (ancienne .bak est supprimée), et prendre un nouveau départ. Avec une limite de 1 mo, cela préserve par exemple, la dernière de 1 MO, sans jamais occuper plus de 2 MO.
Vous pourriez employer un mécanisme similaire avec deux ou plusieurs fichiers. Fondamentalement, déplacez le "rollover" de fichiers, plutôt que de lignes.
si le fichier est peut-être dans un format propriétaire:
Utiliser une base de moteur DB (comme SQLite, comme l'a suggéré), ou d'une autre structurée mécanisme de stockage.
OriginalL'auteur peterchen
Vous pouvez utiliser
log4cxx
avec unRollingFileAppender
pour écrire ces informations dans un fichier journal. LeRollingFileAppender
va gérer déplaçant la souris sur le fichier journal lorsqu'il atteint une certaine taille. Je ne pense pas que c'est exactement ce que vous voulez, mais c'est assez simple, peut-être qu'elle fera.OriginalL'auteur Paul Morie
Il suffit de créer un mappage du fichier de la taille requise (CreateFileMapping ou mmap), écrire les lignes dans la mémoire tampon et de recommencer lorsque le nombre maximum est atteint.
OriginalL'auteur Edouard A.
qui va être difficile puisque le fichier I/O fonctionne avec les octets que le sous-jacent de l'unité de stockage, et non des lignes.
Je veux dire, vous pourriez juste fseek() au début et à tabasser les données précédentes, mais j'ai une intuition qui n'est pas ce que vous voulez.
OriginalL'auteur Jason S
Je l'ai vu faire en gardant le actuelle de la position d'écriture pour le fichier quelque part. Lorsque vous devez ajouter une ligne, vous chercher à la poste, écrivez la ligne, et mettre à jour la position de l'atome de la mode. Si vous débordement, puis vous chercher à zéro avant de vous écrire la ligne. Nous le faisons aujourd'hui pour la taille limitée circulaire fichiers journaux. De le faire sur une ligne de contrainte de base est un peu bizarre, mais pourrait probablement être fait de la même façon. Notre écriture boucle ressemble à quelque chose comme:
La partie la plus délicate est dans le maintien de la actuelle de la position d'écriture et de trouver un moyen de coordonner la lecture du fichier (par exemple, avec la
tail
utilitaire) alors que l'application est écrit. Votre lecteur utilitaire a pour garder une trace de la position d'écriture ainsi donc, il est lu en boucle devient:Ce n'est pas dans une langue donnée - c'est juste de pseudo, mais l'idée est là. Bien sûr, j'ai quitté la manipulation de tous les cas de bord pour le lecteur.
Avec tout ce qui est dit... je suis d'accord avec les autres avis. Ne pas le faire, sauf si vous avez une très bonne raison. Il sonne comme une bonne idée, mais:
grep
,tail
,perl
, etc.Dans l'ensemble, vous serez mieux à l'aide de certains de journalisation de package package qui permet de journal configurable de gestion de fichiers. Jetez un oeil à Apache log4cxx ou Poco
Poco::Enregistreur
.OriginalL'auteur D.Shawley
Simple solution de contournement:
OriginalL'auteur yairchu
Si vous êtes désireux de générer ce fichier pour l'entrée à une autre application, je pense que votre meilleur pari serait de le connecter directement à une relation de la base de données (SQL Server, MySQL, quoi que..), Puis périodiquement générer le fichier en tant que de besoin à partir des données enregistrées.
OriginalL'auteur Eclipse
Pour obtenir autour de la variable taille de la chose, vous aurez probablement se retrouver avec une indirection et un schéma d'allocation. Ce serait composé d'un bloc d'indirection avec un nombre fixe de "pointeurs" dans le fichier, et un "next-à-être-écrit' pointeur, qui tourne autour de N.
Mais le truc principal serait, en ajoutant de l'indirection.
OriginalL'auteur xtofl