6
votes

Ajout de contenu au milieu du fichier .. sans le lire jusqu'à la fin

J'ai lu diverses questions / réponses ici sur UNIX.StacKExchange sur la manière d'ajouter ou de supprimer des lignes vers / depuis un fichier sans avoir à créer un fichier temporaire.

https: / /unix.stackexchange.com/questions/11067/is-Thee-a-way-a-modify-a-file-in-Place?lq=1

Il semble que toutes ces réponses ont besoin d'une seule lecture à la fin du fichier, ce qui peut consommer du temps si l'entrée est un fichier volumineux. Y a-t-il un moyen de contourner ceci? Je m'attendrais à ce qu'un système de fichiers soit mis en œuvre comme une liste liée ... il devrait donc y avoir un moyen d'atteindre les "lignes" requises, puis d'ajouter des trucs (noeud dans des listes liées). Comment puis-je faire cela?

suis-je correct dans la pensée? Ou je manque quelque chose?

PS: J'ai besoin que cela soit fait dans "C" et ne peut pas utiliser de commandes shell.


1 commentaires

Les fichiers ne sont pas implémentés comme des listes liées. Il n'est donc pas un moyen simple d'insérer des données au milieu d'un fichier. Voir SO 10467711 pour le code pour gérer l'insertion de données au milieu d'un fichier, mais sachez qu'il finit par copier toutes les données. Cela suit le point d'insertion à la nouvelle position correcte.


4 Réponses :


9
votes

La réponse courte est que oui , il est possible de modifier le contenu d'un fichier en place, mais non , il n'est pas possible de supprimer ou d'ajouter du contenu dans le milieu du fichier.

Systèmes de fichiers UNIX sont implémentés à l'aide d'un Structure de pointeur de l'inode qui pointe des blocs entiers de données. Chaque ligne d'un fichier texte ne "sait pas" de sa relation avec la ligne précédente ou suivante, elles sont simplement adjacentes les unes aux autres dans le bloc. Pour ajouter du contenu entre ces deux lignes, il faudrait que tous les contenus suivants soient déplacés davantage dans le bloc, en appuyant sur certaines données dans le bloc suivant, ce qui aurait à son tour se déplacer dans le bloc suivant, etc.

in C vous pouvez fopen un fichier pour mettre à jour et lire son contenu et écraser certains du contenu, mais je ne crois pas qu'il y ait (même théoriquement) n'importe quel moyen d'insérer de nouvelles données au milieu ou de suppression de données (sauf pour l'écraser avec les nulls.


2 commentaires

Merci, ce que vous avez dit est correct..mais malheureusement, je ne peux que accepter une réponse. Donc, je pars à upvoting.


Les systèmes de fichiers ne permettent pas de fragmentation? Par exemple, même des fragments ext4 dans certaines circonstances.



4
votes

Vous pouvez modifier un fichier en place, par exemple en utilisant dd code>. xxx pré>

Le problème est que si votre changement change aussi de la longueur, ce ne sera pas tout à fait Travaillez correctement: P>

$ echo -n Joe | dd of=helloworld.txt conv=notrunc bs=1 seek=6
Hello Joeth, how are you today?
$ echo -n Santa Claus | dd of=helloworld.txt conv=notrunc bs=1 seek=6
Hello Santa Clausare you today?


0 commentaires

0
votes

Vous pouvez ouvrir un fichier en mode lecture / écriture. Vous lisez le fichier (ou utilisez "rechercher" pour passer à la position souhaitée, si vous le connaissez), puis écrivez dans le fichier, mais vous écrasez les données qui sont ici (ce n'est pas une insertion). Ensuite, vous pouvez choisir de troncer le fichier à partir du dernier point que vous avez écrit ou de conserver toutes les données restantes après le point que vous avez écrit sans les lire.


0 commentaires

9
votes

AS de Linux 4.1, Fallocat (2) Supports Le drapeau Falloc_fl_Insert_range , qui permet d'insérer un trou d'une longueur donnée au milieu d'un fichier sans réécrire les données suivantes. Cependant, il est plutôt limité: le trou doit être inséré à une limite de bloc de système de fichiers et la taille du trou inséré doit être un multiple de la taille du bloc de système de fichiers. De plus, dans 4.1, cette fonctionnalité n'a été prise en charge que par le système de fichiers XFS, avec Support EXT4 ajouté à 4.2.

Pour tous les autres cas, il est toujours nécessaire de réécrire le reste du fichier, comme indiqué dans d'autres réponses.


1 commentaires

Merci ! Votre réponse correspond-elle à ma question: Unix.stackexchange.com/q/281652/9689 ? Je l'ai cité là-bas, mais si vous l'ajoutez comme votre propre réponse, je serai heureux de la marquer comme réponse et supprimez ma citation. :)