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

Gollum1 gollum1.smeagol1 a gmail.com
Ven 28 Giu 2013 23:58:00 CEST


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...


Maggiori informazioni sulla lista Python