2012-03-28 8 views
11

Sto riscontrando un problema che non ho visto nessuno su StackOverflow o addirittura su google.Python non legge tutto il file di testo

Il mio obiettivo principale è di essere in grado di sostituire le occorrenze di una stringa nel file con un'altra stringa. C'è un modo lì per essere in grado di accedere a tutte le righe nel file.

Il problema è che quando provo a leggere un grande file di testo (1-2 GB) di testo, Python legge solo un sottoinsieme di esso.

Per esempio, io farò davvero un semplice comando come:

newfile = open("newfile.txt","w") 
f = open("filename.txt","r") 
for line in f: 
    replaced = line.replace("string1", "string2") 
    newfile.write(replaced) 

E scrive solo i primi 382 MB del file originale. Qualcuno ha riscontrato questo problema in precedenza?

ho provato alcune soluzioni diverse come l'utilizzo:

import fileinput 
for i, line in enumerate(fileinput.input("filename.txt", inplace=1) 
    sys.stdout.write(line.replace("string1", "string2") 

ma ha lo stesso effetto. Né la lettura del file in blocchi come l'utilizzo di

ho ristretto la scelta per lo più probabile essere una lettura in problema e non un problema di scrittura perché avviene semplicemente per stampare linee. So che ci sono più linee. Quando lo apro in un editor di testo completo come Vim, posso vedere quale dovrebbe essere l'ultima riga, e non è l'ultima riga stampata da python.

Qualcuno può offrire consigli o cose da provare?

Attualmente sto usando una versione a 32 bit di Windows XP con 3,25 GB di RAM, e l'esecuzione di Python 2.7

* Edit soluzione trovata (Grazie Lattyware). L'utilizzo di un Iterator

def read_in_chunks(file, chunk_size=1000): 
    while True: 
     data = file.read(chunk_size) 
     if not data: break 
     yield data 
+1

La lettura riga per riga con un iteratore dovrebbe essere un'operazione pigra, quindi dovrebbe funzionare indipendentemente dalla dimensione del file. Anche se non dovrebbe influenzare la tua situazione, dovrai anche usare '' with'' quando apri i file - è una buona pratica che gestire la chiusura delle eccezioni correttamente. –

+0

Ha funzionato alla grande! Grazie mille. * modifica: ho provato a postare il codice iteratore qui, ma non sarebbe stato formattato, quindi l'ho aggiunto al post originale. – user1297872

+0

Hai provato con un file di testo di dimensioni diverse? C'è qualcosa di strano con il file 382mb - un personaggio strano che viene trattato come la fine del file? – neil

risposta

1

Se si utilizza il file in questo modo:

with open("filename.txt") as f: 
    for line in f: 
     newfile.write(line.replace("string1", "string2")) 

Dovrebbe essere visualizzato solo nella memoria di una riga alla volta, a meno che non si mantiene un riferimento a quella linea in memoria.
Dopo che ogni riga è stata letta, spetterà ai netturbini spazzini per sbarazzarsi di esso. Dare a questo una prova e vedere se funziona per voi :)

22

Prova:

f = open("filename.txt", "rb") 

In Windows, rb significa aprire il file in modalità binaria. Secondo i documenti, la modalità testo e la modalità binaria hanno solo un impatto sui caratteri di fine riga. Ma (se ricordo bene) credo che l'apertura di file in modalità testo su Windows faccia anche qualcosa con EOF (hex 1A).

è anche possibile specificare la modalità di quando si utilizza fileinput:

fileinput.input("filename.txt", inplace=1, mode="rb") 
+0

Anche questo funziona! Mi piace di più questa soluzione, perché è facile cambiare il codice esistente. – user1297872

+0

Come "funziona anche"? Questo è chiaramente il tuo problema. Quale altro approccio ha funzionato bene? Ah, vedo nei commenti, specificando una lunghezza in byte da leggere, invece di usare "readline" – jsbueno

+0

impressionante, ha funzionato per me – Stoyan

2

Sei sicuro che il problema è con la lettura e non con la scrittura fuori? Chiudete il file su cui è scritto, esplicitamente newfile.close() o utilizzando il costrutto with?

Non chiudendo il file di output è spesso la fonte di tali problemi quando il buffering sta andando da qualche parte. Se questo è il tuo caso, la chiusura dovrebbe risolvere le tue soluzioni iniziali.

Problemi correlati