[Python] Ottimizzare la lettura/scrittura di grossi blocchi di dati su file.

Antonio Cavallo a.cavallo a cavallinux.eu
Sab 29 Giu 2013 00:41:14 CEST


prova questo 


def blockread(fp, blocksize=3):
    data = True

    while data:
        data = fp.read(blocksize)
        if data: yield data


total = ""
for i, pack in enumerate(blockread(open("b.py", "rb"))):
    print "%02i" % i, pack




On 28 Jun 2013, at 22:58, Gollum1 <gollum1.smeagol1 a gmail.com> wrote:

> Il 25 giugno 2013 06:58, Giovanni Porcari
> <giovanni.porcari a softwell.it> ha scritto:
>> 
>> Generatori ?
>> 
> 
> Qualcuno riesce a spiegarmi come si usano questi generatori?
> Sincermente, non riesco a capirli (probabilmente anche colpa del mio
> inglese, che va sempre più peggiorando)...
> 
> Cerco di spiegare meglio quello che devo ottenere...
> 
> devo gestire un flusso di dati binario, che può essere anche di
> diversi TB, quindi in flusso molto grande. Lo devo dividere in
> blocchi, ogni blocco poi sarà elaborato in un altro momento. Questi
> blocchi sono praticamente dei file... si tratta praticamente di fare
> uno split del file da diversi TB in molteplici file di dimensione
> fissa... quanto fissa? dipende da quello che l'utente decide al lancio
> del programma, se non decide nulla, si trattano di blocchi da 1MB...
> 
> Ho visto per esperienza che blocchi da 1MB li posso leggere e scrivere
> tutti in un colpo solo con una singola operazione di lettura e una
> singola operazione di scrittura...
> 
> Il problema subentra quando l'utente decidesse di fare blocchi più
> grandi, probabillmente riesco a gestire anche blocchi da 10MB e più in
> singola lettura/scrittura, ma volendo fare una cosa che possa valere
> per tutte le dimensioni che l'utente potrebbe impostare, volevo fare
> in modo che in ogni caso il blocco singolo in lettura/scrittura sia di
> 1MB (che sarebbe quindi la dimensione minima).
> 
> attualmente uso questo codice (funzionante):
> 
>    project.source_size = 0
>    block_counter = 0
>    block = {}
> 
>    while True:
>        block[block_counter] = ib_file_data_support.Block(line_args,
> project, block_counter)
>        block[block_counter].data = fi.read(project.BUFFER_SIZE)
> 
>        # qui dovrei inserire la scrittura sul file del singolo blocco.
> 
>        if not block[block_counter].data:
>            block.pop(block_counter)
>            break
> 
>        # Aggiungo la dimensione del blocco alla dimensione del file sorgente.
>        project.source_size += len(block)
> 
>        # Eseguo tutti i processi che devo sul file del singolo blocco.
> 
>        # ELimino il blocco di dati elaborato.
>        block[block_counter].data = None
> 
>        # Incremento il contatore di blocco e leggo il prossimo blocco.
>        block_counter += 1
> 
> 
> Va da se che se elimino la memorizzazione temporanea in
> block[block_counter].data, non ho neppure più la necessità di
> annullarla alla fine dell'elaborazione.
> 
> Uso la classe Block istanziata su un dizionario, in quanto ho bisogno
> di memorizzare altri dati per ogni blocco, che mi serviranno
> successivamente all'elaborazione della parte binaria, e devono essere
> in un dizionario, in quanto devo poi compararlo con altri dati, e
> potrei avere alla fine dei buchi nella struttura della sequanza dei
> blocchi che vado poi a tenere... (quindi non posso usare una lista).
> 
> Il mio pensiero sarebbe quello di inserire la lettura direttamente
> nella classe Block, infatti ogni istanza della classe contiene anche
> il nome del file in cui deve essere scritto il blocco, quindi mi pare
> il posto più logico su cui fare anche la funzione di split.
> 
> La mia idea era quella di fare questa funzione nella classe, che itera
> la lettura del blocco con un buffer interno pari a 1MB, e lo
> trasferisce sul file, fino al raggiungimento del buffer esterno
> dichiarato dall'utente... o alla fine del file.
> 
> In questo caso io lo farei con un semplice while, come quello già
> utilizzato nello spezzone  d'esempio, solo che invece di True, lo
> faccio ciclare fino al raggiungimento della dimensione passata
> dall'utente.
> 
> Si configura in questo caso l'uso del generatore che mi suggerivate?
> oppure va bene il semplice ciclo di lettura/scrittura che ho pensato
> io?
> 
> Byez
> --
> Gollum1
> Tesssssoro, dov'é il mio tessssoro...
> _______________________________________________
> Python mailing list
> Python a lists.python.it
> http://lists.python.it/mailman/listinfo/python



Maggiori informazioni sulla lista Python