Domanda

Ho un'applicazione che genera alcuni file di log di grandi dimensioni> 500MB.

ho scritto alcune utility in Python che mi permette di navigare velocemente nel file di registro e di trovare i dati di interesse. Ma io ora ottenere alcuni insiemi di dati in cui il file è troppo grande per caricare tutto in memoria.

Ho dunque desidera eseguire la scansione del documento, una volta, costruire un indice e quindi caricare solo la sezione del documento in memoria che io voglio guardare alla volta.

Questo funziona per me, quando apro un 'file' leggere una riga alla volta e memorizzare l'offset con da file.tell (). Posso poi tornare a quella sezione del file in seguito con file.seek (offset, 0).

Il mio problema è, tuttavia, che io possa avere UTF-8 nei file di log quindi ho bisogno di aprirli con il modulo codecs (codecs.open(<filename>, 'r', 'utf-8')). Con l'oggetto risultante posso chiamare cercare e raccontare, ma che non corrispondono.

Suppongo che codec deve fare un po 'di buffering o forse restituisce il carattere conta invece di byte da dire?

C'è un modo per aggirare questo?

È stato utile?

Soluzione

Se fosse vero, questo suona come un insetto o la limitazione del modulo codecs, come è scostamenti di byte e caratteri probabilmente confuse.

Vorrei utilizzare la funzione open() regolare per l'apertura del file, quindi seek() / tell() vi darà Byte offset che sono sempre coerenti. Ogni volta che si desidera leggere, utilizzare f.readline().decode('utf-8').

Attenzione, però, che utilizza la funzione f.read() si può atterrare nel bel mezzo di un carattere multi-byte, producendo così un errore di decodifica UTF-8. readline() funzionerà sempre.

Questa non trasparente gestisce il marchio di byte-ordine per te, ma è probabile che i file di log non hanno distinte base in ogni caso.

Altri suggerimenti

Per UTF-8, non è effettivamente bisogno di aprire il file con codecs.open. Invece, è affidabile per leggere il file come stringa di byte prima, e solo allora decodificare un singola sezione (richiamando il metodo .decode sulla stringa). Rompere il file all'ultima riga è sicuro; l'unico modo non sicuro per dividere, sarebbe nel bel mezzo di un carattere multi-byte (che si può riconoscere dal suo valore di byte> 128).

Molto di ciò che accade con UTF8 in Python ha un senso se si guarda a come è stato fatto in Python 3. Nel tuo caso, si farà un po 'più senso se leggete il capitolo file in Dive Into Python 3 : http://diveintopython3.org/files.html

Il corto di esso, però, è che file.seek e file.tell lavoro con posizioni di byte, mentre i caratteri Unicode possono occupare più byte. Quindi, se si fa:

f.seek(10)
f.read(1)
f.tell()

Si può facilmente ottenere qualcosa di diverso da 17, a seconda di cosa lunghezza di un carattere si legge era.

Update: Non si può fare cercare / dire sull'oggetto restituito da codec.open (). È necessario utilizzare un file normale, e decodificare le stringhe a unicode dopo la lettura.

Non so il motivo per cui non funziona, ma non riesco a farlo funzionare. La cercano sembra funzionare solo una volta, per esempio. Allora avete bisogno di chiudere e riaprire il file, che è, naturalmente, non è utile.

Il tell non usa posizioni dei caratteri, ma non mostra dove la vostra posizione nel flusso è (ma probabilmente in cui l'oggetto file sottostante è nella lettura dal disco).

Quindi, probabilmente a causa di una sorta di buffer di fondo, non si può fare. Ma dopo aver letto deocding funziona bene, in modo da andare per questo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top