Java java.util.regex.Matcher
/replaceAll(...)
API restituisce stringhe, che (se si utilizza la dimensione heap predefinita) potrebbero causare un OOME per input grandi come 20-50M caratteri. Questi 2 metodi possono essere facilmente riscritti a write a Writer
s piuttosto che costruire punture, eliminando efficacemente un punto di errore.Java: regex replacement in file di grandi dimensioni
s' The Matcher
factory method, tuttavia, accetta solo CharSequence
s, che è anche in grado di lanciare un OOME se uso String
s/s/StringBuffer
StringBuilder
s.
Come posso avvolgere un java.io.Reader
ad implementare un'interfaccia CharSequence
(in considerazione del fatto che le mie espressioni regolari possono contenere backreference)? C'è qualche altra soluzione che possa sostituire espressioni regolari nei file e non sia soggetta a OOME su input di grandi dimensioni?
In altre parole, come faccio a implementare una funzionalità simile a quella di GNU sed
in Java (come sed
è noto per affrontare i file grandi come un paio di terabyte, mentre con lo stesso supporto per le espressioni regolari estese)?
Avete solo bisogno di sostituire una singola riga alla volta, o sostenere "tutto il file in una volta sola" sostituzioni? –
'Pattern.matcher()' non crea una nuova stringa. L'oggetto 'Matcher' creato basta tenere un riferimento al CharSequence passata. – nhahtdh
' sed' gestisce i file con il metodo dell'integrazione globale, che è il motivo per cui non richiede un sacco di memoria per file di grandi dimensioni (a meno che il il file ha * molto * lunghe righe o il codice lo istruisce per ricordare un sacco di cose). Se fai lo stesso in Java (ad esempio, leggi una riga, lavoraci sopra, stampala, leggi la riga successiva, risciacqua, ripeti), avrai bisogno di una quantità di memoria simile. A proposito, potresti essere interessato a [Unix4j] (https://code.google.com/p/unix4j/). – Wintermute