Come faccio a persistere su disco un file temporaneo con Python?
-
01-07-2019 - |
Domanda
Sto tentando di utilizzare il "file temporanei" del modulo per la modifica e creazione di file di testo.Una volta che il file è pronto, ho voglia di salvarlo su disco.Ho pensato che sarebbe stato semplice come con 'shutil.copiare'.Tuttavia, ottenere un "permesso negato" IOError:
>>> import tempfile, shutil
>>> f = tempfile.TemporaryFile(mode ='w+t')
>>> f.write('foo')
>>> shutil.copy(f.name, 'bar.txt')
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
shutil.copy(f.name, 'bar.txt')
File "C:\Python25\lib\shutil.py", line 80, in copy
copyfile(src, dst)
File "C:\Python25\lib\shutil.py", line 46, in copyfile
fsrc = open(src, 'rb')
IOError: [Errno 13] Permission denied: 'c:\\docume~1\\me\\locals~1\\temp\\tmpvqq3go'
>>>
Questo non è inteso quando si utilizza il 'tempfile' libreria?C'è un modo migliore per fare questo?(Forse mi sono affacciato qualcosa di molto banale)
Soluzione
Il file che si crea con TemporaryFile
o NamedTemporaryFile
viene rimosso automaticamente quando è chiuso, che è il motivo per cui si ottiene un errore.Se tu non vuoi questo, è possibile utilizzare mkstemp
invece (vedere la documentazione per tempfile).
>>> import tempfile, shutil, os
>>> fd, path = tempfile.mkstemp()
>>> os.write(fd, 'foo')
>>> os.close(fd)
>>> shutil.copy(path, 'bar.txt')
>>> os.remove(path)
Altri suggerimenti
hop è giusto, e dF.non è corretto perché si verifica l'errore.
Dal momento che non hai chiamato f.close()
tuttavia, il file è non rimossa.
Il doc per NamedTemporaryFile
dice:
Se il nome può essere utilizzato per aprire il file una seconda volta, mentre il nome del file temporaneo è ancora aperto, varia tra piattaforme (può essere utilizzato su Unix;non su Windows NT o versioni successive).
E per TemporaryFile
:
Sotto Unix, la voce di directory per il file è stato rimosso subito dopo aver creato il file.Altre piattaforme che non supportano questo;il codice non deve fare affidamento su un file temporaneo creato utilizzando questa funzione di avere o non avere un nome visibile nel file system.
Pertanto, per mantenere un file temporaneo (su Windows), è possibile effettuare le seguenti operazioni:
import tempfile, shutil
f = tempfile.NamedTemporaryFile(mode='w+t', delete=False)
f.write('foo')
file_name = f.name
f.close()
shutil.copy(file_name, 'bar.txt')
os.remove(file_name)
La soluzione Hans Sjunnesson fornito anche fuori, perché copyfileobj
solo copie di file-oggetto simile a file come oggetto, e non il nome del file:
shutil.copyfileobj(fsrc, fdst [lunghezza])
Copiare il contenuto del file come oggetto fsrc il file come oggetto fdst.Il numero intero di lunghezza, se dato, è la dimensione del buffer.In particolare, in negativo, lunghezza valore significa copiare i dati senza loop sopra la sorgente di dati in blocchi;per impostazione predefinita, la lettura dei dati in blocchi per evitare un incontrollato consumo di memoria.Si noti che se la posizione del file di fsrc oggetto non è 0, solo il contenuto dal file corrente posizione alla fine del file verrà copiato.
A partire da python 2.6 è inoltre possibile utilizzare NamedTemporaryFile
con il delete=
opzione impostata su False.In questo modo il file temporaneo sarà accessibile, anche dopo la chiusura di esso.
Nota che su Windows (NT in poi) non è possibile accedere al file una seconda volta mentre è ancora aperto.Devi chiudere prima possibile la copia.Questo non è vero nei sistemi Unix.
Puoi sempre utilizzare shutil.copyfileobj, nel tuo esempio:
new_file = open('bar.txt', 'rw')
shutil.copyfileobj(f, new_file)