En C, est-ce qu’il existe un moyen d’écrire dans un fichier existant, en ajoutant les données en début de fichier ?
En C, est-ce qu’il existe un moyen d’écrire dans un fichier existant, en ajoutant les données en début de fichier ?
Ajouter, non. Tu ne peux ajouter des caractères qu'à partir de la fin.
Si tu remontes plus haut dans le fichier, tu peux seulement remplacer les caractères existants par d'autres.
Si tu veux insérer des caractères, tu ne peux pas faire autrement que écrire dans un second fichier, effacer le premier puis renommer le second avec le nom du premier.
Bonsoir,
Solution sans passer par un fichier intermédiaire, et si la taille du fichier le permet :
- Ouvrir le fichier en R/W
- Lire tous le fichier dans un tableau d'octet en mémoire.
- Replacer le pointeur de fichier en début de fichier.
- Ecrire les nouveaux octets dans le fichier,
- Ecrire le tableau d'octet relu précédemment.
- Fermer le fichier.
Attention, si le fichier intermédiaire est souvent le plus efficace en temps normal, cela n'est pas sans impact sur le système de fichier : par exemple, il peut être impossible d'obtenir à la création du fichier temporaire les droits d'accès accordés au fichier source. Pire, si le droit d'écriture est accordé sur le fichier source, il peut être néanmoins impossible de le supprimer, par exemple (sous Unix) à cause d'un sticky bit ou tout simplement parce qu'on n'a pas les droits d'écriture sur le répertoire qui le contient. Et tout cela est encore plus vrai si le système de fichiers est distant, à travers le réseau.
En outre, si le fichier est très gros, le fichier temporaire peut l'être aussi. Si on souhaite ajouter des informations au début d'un fichier de 2 Go, créer un fichier temporaire de 2 Go lui-aussi peut ne pas être possible du tout.
si la taille dépasse ce que l'on tolère d'allouer comme buffer de travail, cette opération de réécriture peut toujours être effectué par "chunk" en partant de la fin du fichier et en "remontant" vers le point d'insertion désiré (si on généralise : le cas "au début" n'étant qu'un cas particulier où l'offset du point d'insertion = 0…)
la seule condition est que le système de fichiers qui héberge le document supporte le "seek" en général et le "seek" au-delà de la fin du fichier en particulier…
(ce n'est pas toujours le cas d'un système de fichiers en réseau par exemple)
Bonjour,
je penses que tu peux écrire en début de fichier existant sans écraser le reste, mais on pourra me contredire si je me trompe, je n'ai pas essayé :
-tu ouvres ton fichier à partir des appels systèmes comme open (man open) en utilisant les flags O_RDWR et O_TRUNC (l'équivalent d'un "a+" avec fopen je penses)
- tu te déplace en début de fichier avec seek (man lseek), en utilisant la directive whence SEEK_SET et un offset à 0.
-bah ensuite t'as plus qu'à ajouter tes données.
Mais en y réfléchissant il y a de grandes chances que cela écrase les données existantes, mais après tu peux toujours décaler tes données au fur et à mesure, ce qui sera lourd (du coup la copie des données dans un fichier ou un tableau avant de les "ré-ajouter" après insertion des nouvelles données semble le mieux). Mais ce que j'ai proposé est à tester, peut-être que rien ne sera effacé.
Cordialement,
Nullius in verba
Bonjour,
J'ai déjà essayé la méthode de Kaamui autrefois et effectivement cela écrase les données existantes.
Qu'en pensez-vous de cette méthode-ci :
- créer un nouveau fichier (ex : fic2) et l'ouvrir en W
- y écrire les données à ajouter en premier
- ouvrir le fichier qui nous intéresse (ex : fic1) en R
- ecrire dans fic2 chaque caractère lu dans fic1
- fermer les 2 fichiers
- supprimer fic1 (puisqu'on a le résultat dans fic2)
- renommer fic2 en fic1 (si besoin)
Question performance :
Mais cela retombe au même principe que si on veut ajouter des données au début du fichier, il faut décaler tous les anciens données.
Les boutons et adorent être cliqués, donc ne les oubliez pas
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 input: fileDescriptor (opened in RW), insertPosition, dataToInsert, dataToInsertSize assert: fileDescriptor is valid and seek-able assert: insertPosition >= 0 assert: dataToInsert != nil assert: dataToInsertSize > 0 # better if tempBufferSize is multiple of disk sector size, take even multiple of 1024 if you don't know tempBufferSize <- TO_BE_DEFINED alloc tempBuffer of tempBufferSize fileSize <- seek fileDescriptor to EOF readPosition <- fileSize - tempBufferSize writePosition <- fileSize + dataToInsertSize - tempBufferSize while readPosition > insertPosition seek file to readPosition read tempBufferSize bytes from file into tempBuffer seek to writePosition write tempBufferSize bytes into file from tempBuffer readPosition -= tempBufferSize writePosition -= tempBufferSize end while # at this point readPosition is before insertPosition but may be negative # and you still have to move the remaining chunk of bytes from insertPosition to readPosition + tempBufferSize (the latest readPosition before it becomes < insertPosition) # the "special" case readPosition == insertPosition at the end of the loop is eventually not special at all... # in that case, the maths involved here below will correctly move tempBufferSize bytes from insertPosition to the correct writePosition seek fileDescriptor to insertPosition read (readPosition + tempBufferSize - insertPosition) bytes from fileDescriptor into tempBuffer # next write position is (writePosition + tempBufferSize) - (readPosition + tempBufferSize - insertPosition) # thus after simplification seek fileDescriptor to (writePosition - readPosition + insertPosition) write (readPosition + tempBufferSize - insertPosition) bytes into fileDescriptor from tempBuffer # now actually write the data to be inserted seek fileDescriptor to insertPosition write dataToInsertSize bytes into fileDescriptor from dataToInsert free tempBuffer
j'ai lu les commentaires en diagonale ! désolé
Les boutons et adorent être cliqués, donc ne les oubliez pas
Bonjour
Ben le minimum c'est d'essayer tes exemples avant de venir les poser en solution sur un forum...
Non. O_RDWR signifie "read+write" => cela signifie que tu veux à la fois lire et écrire dans le fichier. O_TRUNC signifie "troncature" => le fichier est vidé à l'ouverture. Donc en fait rien à voir avec "ouverture en mode append" qui se fait en utilisant le flag O_APPEND !!! Un autre minimum c'est de lire les liens que tu donnes...
Et donc en écrivant au début du fichier tu n'as pas l'impression d'écraser les données qui y sont ??? Ah ben non elles n'y sont plus vu que le fichier a été ouvert en mode O_TRUNC...
Ah !!! Enfin !!!
Ben pourquoi tu n'as pas testé toi-même ??? Ca prend 20 lignes à taper (en y incluant les commentaires)...
Mon Tutoriel sur la programmation «Python»
Mon Tutoriel sur la programmation «Shell»
Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
Et on poste ses codes entre balises [code] et [/code]
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager