Inserimento di testo in un file esistente tramite Java

Vorrei creare un semplice programma (in Java) che modifica i file di testo, in particolare uno che esegue l’inserimento di parti di testo arbitrarie in posizioni casuali in un file di testo. Questa funzione fa parte di un programma più ampio che sto attualmente scrivendo.

Leggendo la descrizione di java.util.RandomAccessFile, sembra che qualsiasi operazione di scrittura eseguita nel mezzo di un file sovrascriverebbe effettivamente il contenuto in uscita. Questo è un effetto collaterale che vorrei evitare (se ansible).

C’è un modo semplice per raggiungere questo objective?

Grazie in anticipo.

Ok, questa domanda è piuttosto vecchia, ma FileChannels esiste fin da Java 1.4 e non so perché non vengano menzionati da nessuna parte quando si tratta del problema di sostituire o inserire il contenuto nei file. FileChannels sono veloci, usali .

Ecco un esempio (ignorando le eccezioni e alcune altre cose):

public void insert(String filename, long offset, byte[] content) { RandomAccessFile r = new RandomAccessFile(new File(filename), "rw"); RandomAccessFile rtemp = new RandomAccessFile(new File(filename + "~"), "rw"); long fileSize = r.length(); FileChannel sourceChannel = r.getChannel(); FileChannel targetChannel = rtemp.getChannel(); sourceChannel.transferTo(offset, (fileSize - offset), targetChannel); sourceChannel.truncate(offset); r.seek(offset); r.write(content); long newOffset = r.getFilePointer(); targetChannel.position(0L); sourceChannel.transferFrom(targetChannel, newOffset, (fileSize - offset)); sourceChannel.close(); targetChannel.close(); } 

Beh, no, non credo che ci sia un modo per evitare di sovrascrivere il contenuto esistente con una singola chiamata API IO Java standard.

Se i file non sono troppo grandi, basta leggere l’intero file in un ArrayList (una voce per riga) e riscrivere le voci o inserire nuove voci per le nuove linee.

Quindi sovrascrivere il file esistente con nuovo contenuto o spostare il file esistente in un backup e scrivere un nuovo file.

A seconda di quanto sofisticate devono essere le modifiche, potrebbe essere necessario modificare la struttura dei dati.

Un altro metodo sarebbe quello di leggere i caratteri dal file esistente mentre si scrive sul file modificato e modificare lo stream mentre viene letto.

Se Java ha un modo per memorizzare i file della mappa, allora ciò che si può fare è estendere il file alla sua nuova lunghezza, mappare il file, memmove tutti i byte fino alla fine per fare un buco e scrivere i nuovi dati nel foro.

Funziona in C. Mai provato in Java.

Un altro modo in cui ho pensato di fare lo stesso, ma con accesso casuale ai file.

  • Cerca fino alla fine – 1 MB
  • Leggi 1 MB
  • Scrivilo nella posizione originale + dimensione del gap.
  • Ripetere l’operazione per ogni 1 MB precedente fino all’inizio del file.
  • Fermati quando raggiungi la posizione desiderata.

Utilizzare una dimensione del buffer più grande per prestazioni più veloci.

Puoi usare il seguente codice:

 BufferedReader reader = null; BufferedWriter writer = null; ArrayList list = new ArrayList(); try { reader = new BufferedReader(new FileReader(fileName)); String tmp; while ((tmp = reader.readLine()) != null) list.add(tmp); OUtil.closeReader(reader); list.add(0, "Start Text"); list.add("End Text"); writer = new BufferedWriter(new FileWriter(fileName)); for (int i = 0; i < list.size(); i++) writer.write(list.get(i) + "\r\n"); } catch (Exception e) { e.printStackTrace(); } finally { OUtil.closeReader(reader); OUtil.closeWriter(writer); } 

Non so se c’è un modo pratico per farlo dritto diversamente da

  • leggi l’inizio del file e scrivilo a destinazione
  • scrivi il tuo nuovo testo a destinazione
  • leggi il resto del file e scrivilo sul target.

Informazioni sulla destinazione: è ansible build i nuovi contenuti del file in memoria e quindi sovrascrivere il vecchio contenuto del file se i file gestiti non sono così grandi. Oppure puoi scrivere il risultato in un file temporaneo.

La cosa sarebbe probabilmente più semplice da fare con i flussi, RandomAccessFile non sembra essere pensato per l’inserimento nel mezzo (afaik). Controlla il tutorial se ti serve.

Credo che l’unico modo per inserire del testo in un file di testo esistente sia leggere il file originale e scrivere il contenuto in un file temporaneo con il nuovo testo inserito. Quindi cancellare il file originale e rinominare il file temporaneo con il nome originale.

Questo esempio è incentrato sull’inserimento di una singola riga in un file esistente, ma può ancora essere utile.

Se si tratta di un file di testo ,,,, leggi il file esistente in StringBuffer e aggiungi il nuovo contenuto nello stesso StringBuffer ora puoi scrivere SrtingBuffer sul file. quindi ora il file contiene sia il testo esistente che quello nuovo.