2013-06-15 1 views
27

J'ai un fichier temporaire avec du contenu et un script python générant une sortie dans ce fichier. Je veux que cela répète N fois, donc j'ai besoin de réutiliser ce fichier (en fait un tableau de fichiers). Je supprime tout le contenu, de sorte que le fichier temporaire sera vide au prochain cycle. Pour la suppression de contenu que j'utilise ce code:Comment supprimer uniquement le contenu du fichier en python

def deleteContent(pfile): 

    pfile.seek(0) 
    pfile.truncate() 
    pfile.seek(0) # I believe this seek is redundant 

    return pfile 

tempFile=deleteContent(tempFile) 

Ma question est: Y at-il d'autres (mieux, plus ou moins sûr) façon de supprimer tout le contenu sans supprimer réellement le fichier temporaire à partir du disque?

Quelque chose comme tempFile.truncateAll()?

+1

La seconde recherche est en effet redondante. Pourquoi ne pas simplement créer un ** nouveau ** fichier temporaire? –

+0

Parce que pour un script courant, j'ai besoin de ~ 400 fichiers temporaires au lieu de ~ 10. Donc je pense qu'il vaut mieux les recycler. Ai-je tort? – bartimar

+0

Avez-vous rencontré des problèmes réels? Je créerais juste de nouveaux fichiers temporaires et laisserais Python et l'OS nettoyer ceux que j'ai fermés. –

Répondre

58

Comment supprimer uniquement le contenu du fichier en python

Il y a plusieurs façons de définir la taille logique d'un fichier à 0, selon la façon dont vous accédez à ce fichier:

Pour vider un fichier ouvert:

def deleteContent(pfile): 
    pfile.seek(0) 
    pfile.truncate() 

Pour vider un fichier ouvert dont le descripteur de fichier est connu:

def deleteContent(fd): 
    os.ftruncate(fd, 0) 
    os.lseek(fd, 0, os.SEEK_SET) 

Pour vider un fichier fermé (dont le nom est connu)

def deleteContent(fName): 
    with open(fName, "w"): 
     pass 



J'ai un fichier temporaire avec un contenu [ ...] Je dois réutiliser t fichier chapeau

Cela dit, dans le cas général il est probablement pas efficace ni souhaitable de réutiliser un fichier temporaire. Sauf si vous avez des besoins très spécifiques, vous devriez penser à utiliser tempfile.TemporaryFile et un gestionnaire de contexte presque transparente créer/utiliser/supprimer vos fichiers temporaires:

import tempfile 

with tempfile.TemporaryFile() as temp: 
    # do whatever you want with `temp` 

# <- `tempfile` guarantees the file being both closed *and* deleted 
#  on exit of the context manager 
+0

'pfile.truncate (0)' ne réinitialisera pas le pointeur de fichier, donc vous devrez faire un 'pfile.seek (0)' de toute façon. La même chose s'applique à 'os.ftruncate()'. FWIW, vous pouvez obtenir le descripteur de fichier à partir de 'pfile.fileno()', donc 'os.ftruncate (pfile.fileno(), 0)' fonctionnerait, mais vous auriez encore besoin de faire 'pfile.seek (0) 'après. – Aya

+2

De http://docs.python.org/2/library/stdtypes.html#file.truncate 'Notez que si une taille spécifiée dépasse la taille actuelle du fichier, le résultat est dépendant de la plateforme: les possibilités incluent que le fichier peut rester inchangé, augmentez jusqu'à la taille spécifiée comme s'il était rempli de zéros ou augmentez jusqu'à la taille spécifiée avec un nouveau contenu indéfini. 'C'est pourquoi je ne l'ai pas fait. – bartimar

+0

Je regardais effectivement ce document en ce moment. Je comprends que le pointeur de fichier pourrait rester à sa position s'il est toujours valide (c'est-à-dire en pointant avant la nouvelle extrémité logique du fichier). Mais qu'est-ce qu'on tronque le fichier avant la position actuelle? Alors j'ai fait le test. Sous Linux, 'truncate (0)' ne déplace pas la position actuelle comme indiqué par 'ftell()' - mais les écritures suivantes sont faites au début du fichier comme prévu. –

2

Quoi de plus facile que quelque chose comme ceci:

import tempfile 

for i in range(400): 
    with tempfile.TemporaryFile() as tf: 
     for j in range(1000): 
      tf.write('Line {} of file {}'.format(j,i)) 

Cela crée 400 fichiers temporaires et écrit 1000 lignes dans chaque fichier temporaire. Il s'exécute en moins de 1/2 seconde sur ma machine banale. Chaque fichier temporaire du total est créé et supprimé lorsque le gestionnaire de contexte s'ouvre et se ferme dans ce cas. C'est rapide, sécurisé et multi-plateforme.

Utiliser tempfile est beaucoup mieux que d'essayer de le réinventer.

+1

Je pense que 'seek (0)' et 'truncate()' sans cycle est en fait plus facile, mieux, (peut-être plus rapide), et plus agréable à OS/python :) J'avais peur que quelqu'un soit pris sur le réutilisation/recyclage ... Ma question est toujours la même, donc ce n'est pas la réponse. – bartimar

+2

Avez-vous testé cette hypothèse? Avez-vous chronométré pour voir? – dawg

2

Vous pouvez le faire:

def deleteContent(pfile): 
    fn=pfile.name 
    pfile.close() 
    return open(fn,'w') 
2

Je pense que le plus simple est de simplement ouvrir le fichier en mode d'écriture et fermez-le. Par exemple, si votre fichier contient myfile.dat:

"This is the original content" 

Ensuite, vous pouvez simplement écrire:

f = open('myfile.dat', 'w') 
f.close() 

Ce serait effacer tout le contenu. Ensuite, vous pouvez écrire le nouveau contenu dans le fichier:

f = open('myfile.dat', 'w') 
f.write('This is the new content!') 
f.close() 
Questions connexes