Escrevendo no início de um arquivo de texto Java

Eu preciso escrever algo no começo de um arquivo de texto. Eu tenho um arquivo de texto com conteúdo e eu quero escrever algo antes deste conteúdo. Diga que eu tenho;

Boa tarde senhor, como vai você hoje?
Eu estou bem, como vai você?
Obrigado por perguntar, eu sou ótimo

Depois de modificar, quero que seja assim:

Página 1-cena 59
25.05.2011

Boa tarde senhor, como vai você hoje?
Eu estou bem, como vai você?
Obrigado por perguntar, eu sou ótimo

Apenas inventei o conteúdo 🙂 Como posso modificar um arquivo de texto dessa maneira?

Você não pode realmente modificá- lo dessa maneira – os filesystems geralmente não permitem que você insira dados em locais arbitrários – mas você pode:

  • Crie um novo arquivo
  • Escreva o prefixo para ele
  • Copie os dados do arquivo antigo para o novo arquivo
  • Mova o arquivo antigo para um local de backup
  • Mova o novo arquivo para o local do arquivo antigo
  • Opcionalmente, exclua o arquivo de backup antigo

Apenas no caso, será útil para alguém aqui é o código-fonte completo do método para pré-append linhas a um arquivo usando a biblioteca Apache Commons IO . O código não lê o arquivo inteiro na memory, então funciona em arquivos de qualquer tamanho.

public static void prependPrefix(File input, String prefix) throws IOException { LineIterator li = FileUtils.lineIterator(input); File tempFile = File.createTempFile("prependPrefix", ".tmp"); BufferedWriter w = new BufferedWriter(new FileWriter(tempFile)); try { w.write(prefix); while (li.hasNext()) { w.write(li.next()); w.write("\n"); } } finally { IOUtils.closeQuietly(w); LineIterator.closeQuietly(li); } FileUtils.deleteQuietly(input); FileUtils.moveFile(tempFile, input); } 

Eu acho que o que você quer é access random. Confira o tutorial de java relacionado . No entanto, não acredito que você possa inserir dados em um ponto arbitrário no arquivo; Se bem me lembro, você só replaceia os dados. Se você quisesse inserir, você teria que ter seu código

  1. copiar um bloco,
  2. replace com seu material novo,
  3. copie o próximo bloco,
  4. sobrescrever com o bloco copiado anteriormente,
  5. retornar a 3 até não mais blocos

Como sugerido pelo @atk, java.nio.channels.SeekableByteChannel é uma boa interface. Mas está disponível somente a partir de 1.7.

Atualização: Se você não tem nenhum problema usando o FileUtils, use

 String fileString = FileUtils.readFileToString(file); 

Esta não é uma resposta direta à pergunta, mas muitas vezes os arquivos são acessados ​​via InputStreams. Se este é o seu caso de uso, então você pode encadear streams de input via SequenceInputStream para obter o mesmo resultado. Por exemplo

 InputStream inputStream = new SequenceInputStream(new ByteArrayInputStream("my line\n".getBytes()), new FileInputStream(new File("myfile.txt")));