Scopo | Creare risorse temporanee nel filesystem |
Versione Python | Dalla 1.4 con importanti revisioni di sicurezza nella 2.3 |
A partire dal 1 gennaio 2021 le versioni 2.x di Python non sono piu' supportate. Ti invito a consultare la corrispondente versione 3.x dell'articolo per il modulo tempfile
Molti programmi devono creare dei file per scrivere dati intermedi. Creare in sicurezza questi file con nomi univoci, in modo che nessuno possa identificarli nel tentativo di forzare l'applicazione è impegnativo. Il modulo
tempfile
fornisce parecchie funzioni per creare risorse nel filesystem in sicurezza.
TemporaryFile()
apre e restituisce un file non-nominato,
NamedTemporaryFile()
apre e restituisce un file con un nome, mentre
mkdtemp()
crea una directory temporanea e ne restituisce il nome.
Se un'applicazione necessita di un file temporaneo per salvare dei dati, ma non deve dividere quel file con altri programmi, la scelta migliore è quella di creare il file con la funzione
TemporaryFile()
. Essa crea un file e, nelle piattaforme in cui è possibile, esegue immediatamente un
unlink
. Questo rende impossibile ad un altro programma di trovare od aprire il file, visto che non esiste nessun riferimento ad esso nella tabella del filesystem. Il file creato da TemporaryFile() viene eliminato automaticamente quando viene chiuso.
import os
import tempfile
print 'Creazione di un nome di file:'
filename = '/tmp/indovina_il_nome.%s.txt' % os.getpid()
temp = open(filename, 'w+b')
try:
print 'temp:', temp
print 'temp.name:', temp.name
finally:
temp.close()
# Elimina espressamente il file temporaneo
os.remove(filename)
print
print 'TemporaryFile:'
temp = tempfile.TemporaryFile()
try:
print 'temp:', temp
print 'temp.name:', temp.name
finally:
# Elimina il file automaticamente
temp.close()
L'esempio illustra la differenza tra il creare un file temporaneo usando una operatività comune per impostarne il nome, e l'usare la funzione TemporaryFile(). Si noti che il file restituito da TemporaryFile non ha un nome.
$ python tempfile_TemporaryFile.py Creazione di un nome di file: temp:temp.name: /tmp/indovina_il_nome.19029.txt TemporaryFile: temp: ', mode 'w+b' at 0x94488e0> temp.name:
In modalità predefinita, l'handle del file viene creato con modalità 'w+b', in modo che si comporti consistentemente su tutte le piattaforme ed un programma possa scrivere o leggere da esso.
import os
import tempfile
temp = tempfile.TemporaryFile()
try:
temp.write('Qualche dato')
temp.seek(0)
print temp.read()
finally:
temp.close()
Dopo la scrittura si deve 'riavvolgere' l'handle del file usando
seek()
per potere leggere di nuovo i dati da esso.
$ python tempfile_TemporaryFile_binary.py Qualche dato
Se si vuole che il file lavori in formato testo, si passa mode='w+t' quando lo si crea:
import tempfile
f = tempfile.TemporaryFile(mode='w+t')
try:
f.writelines(['primo\n', 'secondo\n'])
f.seek(0)
for line in f:
print line.rstrip()
finally:
f.close()
L'handle del file considera i dati come testo:
$ python tempfile_TemporaryFile_text.py primo secondo
Ci sono situazioni, comunque, dove avere un file temporaneo con un nome è importante. Se una applicazione sviluppa processi multipli, od anche host, nominare il file diventa il modo più semplice per passarlo tra le parti dell'applicazione. La funzione
NamedTemporaryFile()
crea un file con un nome, al quale si accede con l'attributo
name
.
import os
import tempfile
temp = tempfile.NamedTemporaryFile()
try:
print 'temp:', temp
print 'temp.name:', temp.name
finally:
# Elimina il file automaticamente
temp.close()
print 'Esiste dopo la chiusura:', os.path.exists(temp.name)
Anche se il file ha un nome viene comunque rimosso non appena l'handle viene chiuso.
$ python tempfile_NamedTemporaryFile.py temp:', mode 'w+b' at 0x9756890> temp.name: /tmp/tmpLQ53Av Esiste dopo la chiusura: False
Se occorrono diversi file temporanei, potrebbe essere molto più conveniente creare una singola direcotry temporanea, qundi aprire tutti i file in essa. Per creare una directory temporanea si usa
mkdtemp()
.
import os
import tempfile
directory_name = tempfile.mkdtemp()
print directory_name
# Lo script elimina la directory
os.removedirs(directory_name)
Visto che la directory non è "aperta" di per sè, occorre occuparsi della rimozione quando non serve più.
$ python tempfile_mkdtemp.py /tmp/tmpzi5Mcm
Per scopi di debug, potrebbe essere utile includere qualche indicazione circa l'origine dei file temporanei. Sebbene ovviamente sia meno sicuro rispetto ai file temporanei strettamente anonimi, includere una porzione prevedibile nel nome consente di trovare il file da esaminare mentre il programma lo sta usando. Tutte le funzioni fin qui descritte ricevono tre parametri per consentire il controllo dei nomi dei file fino ad un certo punto. I nomi sono generati usando la formula:
dir + prefix + random + suffix
dove tutti i valori tranne 'random' possono essere passati come parametro a TemporaryFile(), NamedTemporaryFIle() e mkdtemp(). Ad esempio:
import tempfile
temp = tempfile.NamedTemporaryFile(suffix='_suffisso',
prefix='prefisso_',
dir='/tmp',
)
try:
print 'temp:', temp
print 'temp.name:', temp.name
finally:
temp.close()
I parametri prefix e suffix sono combinati assieme ad una stringa casuale di caratteri per costruire il nome del file, ed il parametro dir viene ricevuto così com'è ed usato come locazione del nuovo file.
$ python tempfile_NamedTemporaryFile_args.py temp:', mode 'w+b' at 0x9ed2890> temp.name: /tmp/prefisso_35K6h5_suffisso
Se non viene specificata esplicitamente una destinazione attraverso il parametro dir , il percorso usato per i file temporanei assumerà valori diversi a seconda della piattaforma di esecuzione e delle impostazioni. Il modulo tempfile include due fuzioni per interrogare le impostazioni che sono usate in fase di esecuzione.
import tempfile
print 'gettempdir():', tempfile.gettempdir()
print 'gettempprefix():', tempfile.gettempprefix()
gettempdir() restituisce la directory predefinita che conterrà tutti i file temporanei e gettempprefix() ritorna la stringa del prefisso per i nomi del nuovo file e directory.
$ python tempfile_settings.py gettempdir(): /tmp gettempprefix(): tmp
Il valore restituito da gettempdir() viene impostato in base ad un algoritmo che cerca attraverso un elenco di locazioni il primo posto nel quale il processo corrente può creare un file. Dalla documentazione della libreria:
Python cerca in una lista standard di directory ed imposta tempdir come la prima nella quale l'utente chiamante può creare il file. La lista comprende:
Se il programma deve usare un locazione globale per tutti i file temporanei che deve essere creata esplicitamente ma non lo si vuole fare attraverso una di queste variabili di ambiente, si può impostare tempfile.tempdir direttamente.
import tempfile
tempfile.tempdir = '/Ho/cambiato/questo/percorso'
print 'gettempdir():', tempfile.gettempdir()
$ python tempfile_tempdir.py gettempdir(): /Ho/cambiato/questo/percorso
Vedere anche: