J'utilise Python et je voudrais insérer une chaîne de caractères dans un fichier texte sans effacer ou copier le fichier. Comment puis-je le faire ?
Réponses
Trop de publicités?Malheureusement, il n'existe aucun moyen d'insérer au milieu d'un fichier sans le réécrire. Comme les posters précédents l'ont indiqué, vous pouvez ajouter à un fichier ou écraser une partie de celui-ci en utilisant seek mais si vous voulez ajouter des éléments au début ou au milieu, vous devrez le réécrire.
C'est un problème lié au système d'exploitation, pas à Python. C'est la même chose dans tous les langages.
Ce que je fais habituellement, c'est lire le fichier, faire les modifications et l'écrire dans un nouveau fichier appelé monfichier.txt.tmp ou quelque chose comme ça. C'est mieux que de lire tout le fichier en mémoire car le fichier peut être trop grand pour cela. Une fois le fichier temporaire terminé, je le renomme de la même façon que le fichier original.
C'est un moyen sûr et efficace de procéder, car si l'écriture du fichier se bloque ou s'interrompt pour une raison quelconque, vous avez toujours votre fichier original intact.
Cela dépend de ce que vous voulez faire. Pour ajouter, vous pouvez l'ouvrir avec "a" :
with open("foo.txt", "a") as f:
f.write("new line\n")
Si vous voulez préprendre quelque chose, vous devez d'abord lire le fichier :
with open("foo.txt", "r+") as f:
old = f.read() # read everything in the file
f.seek(0) # rewind
f.write("new line\n" + old) # write the new line before
La réécriture d'un fichier en place se fait souvent en sauvegardant l'ancienne copie avec un nom modifié. Les utilisateurs d'Unix ajoutent un ~
pour marquer l'ancien. Les utilisateurs de Windows font toutes sortes de choses : ils ajoutent .bak ou .old, renomment entièrement le fichier ou mettent le ~ devant le nom.
import shutil
shutil.move( afile, afile+"~" )
destination= open( aFile, "w" )
source= open( aFile+"~", "r" )
for line in source:
destination.write( line )
if <some condition>:
destination.write( >some additional line> + "\n" )
source.close()
destination.close()
Au lieu de shutil
vous pouvez utiliser ce qui suit.
import os
os.rename( aFile, aFile+"~" )
Le module fileinput de la bibliothèque standard de Python réécrira un fichier inplace si vous utilisez le paramètre inplace=1 :
import sys
import fileinput
# replace all occurrences of 'sit' with 'SIT' and insert a line after the 5th
for i, line in enumerate(fileinput.input('lorem_ipsum.txt', inplace=1)):
sys.stdout.write(line.replace('sit', 'SIT')) # replace 'sit' and write
if i == 4: sys.stdout.write('\n') # write a blank line after the 5th line
Le module mmap de Python vous permettra d'insérer dans un fichier. L'exemple suivant montre comment cela peut être fait sous Unix (le module mmap de Windows peut être différent). Notez que cette méthode ne gère pas toutes les conditions d'erreur et que vous risquez de corrompre ou de perdre le fichier d'origine. De plus, cette méthode ne gère pas les chaînes unicode.
import os
from mmap import mmap
def insert(filename, str, pos):
if len(str) < 1:
# nothing to insert
return
f = open(filename, 'r+')
m = mmap(f.fileno(), os.path.getsize(filename))
origSize = m.size()
# or this could be an error
if pos > origSize:
pos = origSize
elif pos < 0:
pos = 0
m.resize(origSize + len(str))
m[pos+len(str):] = m[pos:origSize]
m[pos:pos+len(str)] = str
m.close()
f.close()
Il est également possible de faire cela sans mmap avec des fichiers ouverts en mode 'r+', mais c'est moins pratique et moins efficace car il faudrait lire et stocker temporairement le contenu du fichier de la position d'insertion à EOF - ce qui pourrait être énorme.
- Réponses précédentes
- Plus de réponses