É esta a melhor maneira de reescrever o conteúdo de um arquivo em Java?
Pergunta
Eu quero reescrever o conteúdo de um arquivo.
O que tenho pensado até agora é a seguinte:
- Salvar o nome do arquivo
- Exclua o arquivo existente
- Criar um novo arquivo vazio com o mesmo nome
- Escrever o conteúdo desejado para o arquivo vazio
Esta é a melhor maneira? Ou há uma maneira mais direta, isto é, não ter que excluir e criar arquivos, mas simplesmente alterar o conteúdo?
Solução
Para foo.log arquivo de substituição com FileOutputStream:
File myFoo = new File("foo.log");
FileOutputStream fooStream = new FileOutputStream(myFoo, false); // true to append
// false to overwrite.
byte[] myBytes = "New Contents\n".getBytes();
fooStream.write(myBytes);
fooStream.close();
ou com FileWriter:
File myFoo = new File("foo.log");
FileWriter fooWriter = new FileWriter(myFoo, false); // true to append
// false to overwrite.
fooWriter.write("New Contents\n");
fooWriter.close();
Outras dicas
Eu recomendo usando FileUtil do Apache comum para isso. Eu encontrei este inestimável pacote. É fácil de usar e igualmente importante é fácil de ler / entender quando você voltar um pouco mais tarde.
//Create some files here
File sourceFile = new File("pathToYourFile");
File fileToCopy = new File("copyPath");
//Sample content
org.apache.commons.io.FileUtils.writeStringToFile(sourceFile, "Sample content");
//Now copy from source to copy, the delete source.
org.apache.commons.io.FileUtils.copyFile(sourceFile, fileToCopy);
org.apache.commons.io.FileUtils.deleteQuietly(sourceFile);
Mais informação pode ser encontrada em: http://commons.apache.org/io /api-release/org/apache/commons/io/FileUtils.html
Veja: java.io.RandomAccessFile
Você vai querer abrir um arquivo de leitura e escrita, assim:
RandomAccessFile raf = new RandomAccessFile("filename.txt", "rw");
String tmp;
while (tmp = raf.readLine() != null) {
// Store String data
}
// do some string conversion
raf.seek(0);
raf.writeChars("newString");
A menos que você está apenas a adição de conteúdo, no final, é razoável fazê-lo dessa maneira. Se você está anexando, tente FileWriter com o construtor de acréscimo.
Um pouco melhor forma seria:
- Gerar novo nome de arquivo (por exemplo foo.txt.new)
- Escrever conteúdo atualizado para o novo arquivo.
- Do renomeação atômica de foo.txt.new para foo.txt
Infelizmente, renameTo é não garantida fazer renomeação atômica.
No exemplo abaixo, a "false" faz com que o arquivo a ser substituído, é verdade causaria o oposto.
File file=new File("C:\Path\to\file.txt");
DataOutputStream outstream= new DataOutputStream(new FileOutputStream(file,false));
String body = "new content";
outstream.write(body.getBytes());
outstream.close();
Há momentos em que um pode querer manter um enorme arquivo vazio, de modo a evitar custos extra do OS alocar espaço na base de necessidade. Isto é geralmente feito por bancos de dados, máquinas virtuais e também em programas de lote que processam e gravação em massa de dados. Isso melhoraria o desempenho do aplicativo de forma significativa. Nestes casos, escrevendo um novo arquivo e renomeá-lo realmente não ajuda. Em vez disso, o arquivo vazio terá de ser preenchido. Ou seja, quando um deve ir para o modo de substituição.
Goiaba File.write " Substitui um arquivo com o conteúdo de um array de bytes ":
Files.write(bytes, new File(path));