Мне нужно многократно добавлять текст к существующему файлу на Java. Как я могу это сделать?
Как добавить текст в существующий файл на Java?
Ответы (30)
Вы делаете это для ведения журнала? В таком случае существует несколько библиотек для этого. Двумя наиболее популярными являются Log4j и Вернуться.
Java 7+
Для одноразовой задачи класс файлов упрощает это:
try {
Files.write(Paths.get("myfile.txt"), "the text".getBytes(), StandardOpenOption.APPEND);
}catch (IOException e) {
//exception handling left as an exercise for the reader
}
Осторожно: описанный выше подход приведет к выдаче NoSuchFileException
, если файл еще не существует. Он также не добавляет новую строку автоматически (что часто требуется при добавлении в текстовый файл). Другой подход - передать параметры CREATE
и APPEND
, которые сначала создадут файл, если он еще не существует:
private void write(final String s) throws IOException {
Files.writeString(
Path.of(System.getProperty("java.io.tmpdir"), "filename.txt"),
s + System.lineSeparator(),
CREATE, APPEND
);
}
Однако, если вы будете писать в один и тот же файл много раз, приведенные выше фрагменты должны открывать и закрывать файл на диске много раз, что является медленной операцией. В этом случае BufferedWriter
быстрее:
try(FileWriter fw = new FileWriter("myfile.txt", true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw))
{
out.println("the text");
//more code
out.println("more text");
//more code
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
Примечания:
- Второй параметр конструктора
FileWriter
будет указывать ему на добавление в файл, а не на запись нового файла. (Если файл не существует, он будет создан.) - Для дорогих писателей (например,
FileWriter
) рекомендуется использоватьBufferedWriter
. - Использование
PrintWriter
дает вам доступ к синтаксисуprintln
, к которому вы, вероятно, привыкли сSystem.out
. - Но обертки
BufferedWriter
иPrintWriter
не нужны.
Старая версия Java
try {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("myfile.txt", true)));
out.println("the text");
out.close();
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
Обработка исключений
Если вам нужна надежная обработка исключений для более старой версии Java, она становится очень подробной:
FileWriter fw = null;
BufferedWriter bw = null;
PrintWriter out = null;
try {
fw = new FileWriter("myfile.txt", true);
bw = new BufferedWriter(fw);
out = new PrintWriter(bw);
out.println("the text");
out.close();
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
finally {
try {
if(out != null)
out.close();
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
try {
if(bw != null)
bw.close();
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
try {
if(fw != null)
fw.close();
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
}
new BufferedWriter(...)
вызывает исключение; Будет ли FileWriter
закрываться? Я предполагаю, что он не будет закрыт, потому что метод close()
(в нормальных условиях) будет вызываться для объекта out
, который в этом случае не будет инициализирован - поэтому на самом деле метод close()
не будет вызван - ›файл будет открыт, но не закроется. Итак, ИМХО, оператор try
должен выглядеть так try(FileWriter fw = new FileWriter("myFile.txt")){ Print writer = new ....//code goes here }
И он должен flush()
писатель перед выходом из блока try
!!!
- person Svetlin Zarev; 14.01.2014
Files.write
вместо PrintWriter из BufferedWriter из FileWriter?
- person assylias; 18.05.2015
File
и конструкторы на основе имени файла PrintWriter
упоминают, что они буферизуются автоматически. Но когда PrintWriter
оборачивает другой Writer
, в документации нет комментариев о том, добавляет ли он еще один уровень буферизации или нет. Учитывая двусмысленность, лучше всего явно указать BufferedWriter
, как в этом ответе.
- person Evgeni Sergeev; 14.11.2015
out
определяется только в блоке try
. В блоке finally
его нет. Вам придется переместить объявление out
из блока try
. Именно эту проблему решает синтаксис Java 7+. Как я уже отмечал, я оставил обработку исключений для читателя; Думаю, это выходит за рамки этого ответа.
- person Kip; 31.03.2016
StandardOpenOption.APPEND
не будет его создавать - это похоже на тихий сбой, поскольку он также не вызовет исключения. (2) Использование .getBytes()
будет означать, что перед добавленным текстом или после него нет символа возврата. Добавили альтернативный ответ для решения этих проблем.
- person Steve Chambers; 01.06.2017
catch
пустым, вы его не увидите. Я обновил свой ответ, чтобы отразить эти проблемы, и добавил ссылку на ваш ответ.
- person Kip; 03.06.2017
flush()
, чтобы заставить его немедленно очистить буфер (записать содержимое).
- person Kip; 17.07.2017
Вы можете использовать fileWriter
с флагом, установленным на true
, для добавления.
try
{
String filename= "MyFile.txt";
FileWriter fw = new FileWriter(filename,true); //the true will append the new data
fw.write("add a line\n");//appends the string to the file
fw.close();
}
catch(IOException ioe)
{
System.err.println("IOException: " + ioe.getMessage());
}
close
следует поместить в finally
блок, как показано в ответе @etech, на случай, если между созданием FileWriter и вызовом близко.
- person Pshemo; 14.03.2015
fw.close()
в блоке finally, без вложенного try / catch (.close()
может выбросить IOException
)
- person Kip; 17.08.2016
try(FileWriter fw = new FileWriter(filename,true)){ // Whatever }catch(IOException ex){ ex.printStackTrace(); }
- person php_coder_3809625; 18.08.2016
Разве все ответы здесь с блоками try / catch не должны содержать части .close (), содержащиеся в блоке finally?
Пример отмеченного ответа:
PrintWriter out = null;
try {
out = new PrintWriter(new BufferedWriter(new FileWriter("writePath", true)));
out.println("the text");
} catch (IOException e) {
System.err.println(e);
} finally {
if (out != null) {
out.close();
}
}
Кроме того, начиная с Java 7, вы можете использовать инструкцию try-with-resources. Для закрытия объявленных ресурсов не требуется блок finally, потому что он обрабатывается автоматически, а также является менее подробным:
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("writePath", true)))) {
out.println("the text");
} catch (IOException e) {
System.err.println(e);
}
out
выходит за пределы области видимости, он автоматически закрывается при сборке мусора, верно? В вашем примере с блоком finally
, я думаю, вам действительно нужна еще одна вложенная попытка / уловка вокруг out.close()
, если я правильно помню. Решение Java 7 довольно хорошее! (Я не занимался разработкой Java со времен Java 6, поэтому я не был знаком с этим изменением.)
- person Kip; 21.08.2013
flush
для второго подхода?
- person syfantid; 14.02.2016
Использование Apache Commons 2.1:
FileUtils.writeStringToFile(file, "String to append", true);
Немного расширив ответ Кипа, вот простой метод Java 7+ для добавления новой строки в файл, создав его, если он еще не существует:
try {
final Path path = Paths.get("path/to/filename.txt");
Files.write(path, Arrays.asList("New line to append"), StandardCharsets.UTF_8,
Files.exists(path) ? StandardOpenOption.APPEND : StandardOpenOption.CREATE);
} catch (final IOException ioe) {
// Add your own exception handling...
}
Дополнительные примечания:
В приведенном выше примере используется _ 2_ перегрузка, которая записывает строки текст в файл (т.е. аналогично команде
println
). Чтобы просто написать текст до конца (т.е. аналогично командеprint
), можно использовать альтернативу _ 5_ может использоваться перегрузка, передавая байтовый массив (например,"mytext".getBytes(StandardCharsets.UTF_8)
).Параметр
CREATE
будет работать только в том случае, если указанный каталог уже существует - в противном случае выдаетсяNoSuchFileException
. При необходимости после установкиpath
можно добавить следующий код для создания структуры каталогов:Path pathParent = path.getParent(); if (!Files.exists(pathParent)) { Files.createDirectories(pathParent); }
.CREATE
сделает эту работу за тебя.
- person LearningToNLP; 29.01.2019
.CREATE
используется, когда файл уже существует, он ничего не добавляет - исключение не генерируется, но существующее содержимое файла остается неизменным.
- person Steve Chambers; 14.08.2020
APPEND
+ CREATE
работает отлично, проверка не требуется: Files.write(Paths.get("test.log"), (Instant.now().toString() + "\r\n").getBytes(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
- person lapo; 12.11.2020
Убедитесь, что поток правильно закрыт во всех сценариях.
Немного тревожно, сколько из этих ответов оставляют дескриптор файла открытым в случае ошибки. Ответ https://stackoverflow.com/a/15053443/2498188 - в деньгах, но только потому, что BufferedWriter()
не может бросить. Если бы это было возможно, то исключение оставило бы объект FileWriter
открытым.
Более общий способ сделать это, не заботясь о том, может ли BufferedWriter()
выбросить:
PrintWriter out = null;
BufferedWriter bw = null;
FileWriter fw = null;
try{
fw = new FileWriter("outfilename", true);
bw = new BufferedWriter(fw);
out = new PrintWriter(bw);
out.println("the text");
}
catch( IOException e ){
// File writing/opening failed at some stage.
}
finally{
try{
if( out != null ){
out.close(); // Will close bw and fw too
}
else if( bw != null ){
bw.close(); // Will close fw too
}
else if( fw != null ){
fw.close();
}
else{
// Oh boy did it fail hard! :3
}
}
catch( IOException e ){
// Closing the file writers failed for some obscure reason
}
}
Редактировать:
Начиная с Java 7, рекомендуется использовать «попробовать с ресурсами» и позволить JVM справиться с этим:
try( FileWriter fw = new FileWriter("outfilename", true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw)){
out.println("the text");
}
catch( IOException e ){
// File writing/opening failed at some stage.
}
PrintWriter.close()
не объявлен как throws IOException
в документы. Глядя на его исходный код, метод close()
действительно , не может выбросить IOException
, потому что он перехватывает его из основного потока и устанавливает флаг. Поэтому, если вы работаете над кодом для следующего космического корабля "Шаттл" или системы измерения дозы рентгеновского излучения, вы должны использовать PrintWriter.checkError()
после попытки out.close()
. Это действительно должно было быть задокументировано.
- person Evgeni Sergeev; 14.11.2015
XX.close()
должен быть в своем собственном try / catch, верно? Например, out.close()
может вызвать исключение, и в этом случае bw.close()
и fw.close()
никогда не будут вызваны, а fw
- тот, который наиболее критичен для закрытия.
- person Kip; 06.04.2016
В Java-7 это тоже можно сделать так:
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
//---------------------
Path filePath = Paths.get("someFile.txt");
if (!Files.exists(filePath)) {
Files.createFile(filePath);
}
Files.write(filePath, "Text to be added".getBytes(), StandardOpenOption.APPEND);
java 7+
По моему скромному мнению, поскольку я поклонник простой java, я бы предложил кое-что, что это комбинация вышеупомянутых ответов. Может, я опаздываю на вечеринку. Вот код:
String sampleText = "test" + System.getProperty("line.separator");
Files.write(Paths.get(filePath), sampleText.getBytes(StandardCharsets.UTF_8),
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
Если файл не существует, он создает его, а если уже существует, добавляет sampleText к существующему файлу. Использование этого избавляет вас от добавления ненужных библиотек в путь к классам.
Это можно сделать одной строкой кода. Надеюсь это поможет :)
Files.write(Paths.get(fileName), msg.getBytes(), StandardOpenOption.APPEND);
Я просто добавляю мелкую деталь:
new FileWriter("outfilename", true)
2-й параметр (true) - это функция (или интерфейс), называемая добавляемым (http://docs.oracle.com/javase/7/docs/api/java/lang/Appendable.html). Он отвечает за возможность добавления некоторого контента в конец определенного файла / потока. Этот интерфейс реализован начиная с Java 1.5. Каждый объект (например, BufferedWriter, CharArrayWriter, CharBuffer, FileWriter, FilterWriter, LogStream, OutputStreamWriter, PipedWriter, PrintStream, PrintWriter, StringBuffer, StringBuilder, StringWriter, Writer) с этим интерфейсом может использоваться для добавления содержимого.
Другими словами, вы можете добавить какой-то контент в свой gzip-файл или какой-нибудь http-процесс.
Использование java.nio. Файлы вместе с java.nio.file. StandardOpenOption
PrintWriter out = null;
BufferedWriter bufWriter;
try{
bufWriter =
Files.newBufferedWriter(
Paths.get("log.txt"),
Charset.forName("UTF8"),
StandardOpenOption.WRITE,
StandardOpenOption.APPEND,
StandardOpenOption.CREATE);
out = new PrintWriter(bufWriter, true);
}catch(IOException e){
//Oh, no! Failed to create PrintWriter
}
//After successful creation of PrintWriter
out.println("Text to be appended");
//After done writing, remember to close!
out.close();
Это создает BufferedWriter
using Files, который принимает параметры StandardOpenOption
, и автоматическую очистку PrintWriter
из результирующего BufferedWriter
. Затем можно вызвать метод println()
PrintWriter
для записи в файл.
Параметры StandardOpenOption
, используемые в этом коде: открывает файл для записи, только добавляет в файл и создает файл, если он не существует.
Paths.get("path here")
можно заменить на new File("path here").toPath()
. И Charset.forName("charset name")
может быть изменен для соответствия желаемому Charset
.
Пример с использованием Guava:
File to = new File("C:/test/test.csv");
for (int i = 0; i < 42; i++) {
CharSequence from = "some string" + i + "\n";
Files.append(from, to, Charsets.UTF_8);
}
Попробуйте с bufferFileWriter.append, у меня работает.
FileWriter fileWriter;
try {
fileWriter = new FileWriter(file,true);
BufferedWriter bufferFileWriter = new BufferedWriter(fileWriter);
bufferFileWriter.append(obj.toJSONString());
bufferFileWriter.newLine();
bufferFileWriter.close();
} catch (IOException ex) {
Logger.getLogger(JsonTest.class.getName()).log(Level.SEVERE, null, ex);
}
String str;
String path = "C:/Users/...the path..../iin.txt"; // you can input also..i created this way :P
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(new FileWriter(path, true));
try
{
while(true)
{
System.out.println("Enter the text : ");
str = br.readLine();
if(str.equalsIgnoreCase("exit"))
break;
else
pw.println(str);
}
}
catch (Exception e)
{
//oh noes!
}
finally
{
pw.close();
}
это сделает то, что вы собираетесь ..
Вы также можете попробовать это:
JFileChooser c= new JFileChooser();
c.showOpenDialog(c);
File write_file = c.getSelectedFile();
String Content = "Writing into file"; //what u would like to append to the file
try
{
RandomAccessFile raf = new RandomAccessFile(write_file, "rw");
long length = raf.length();
//System.out.println(length);
raf.setLength(length + 1); //+ (integer value) for spacing
raf.seek(raf.length());
raf.writeBytes(Content);
raf.close();
}
catch (Exception e) {
//any exception handling method of ur choice
}
Лучше использовать try-with-resources, чем все эти pre-java 7, наконец, бизнес
static void appendStringToFile(Path file, String s) throws IOException {
try (BufferedWriter out = Files.newBufferedWriter(file, StandardCharsets.UTF_8, StandardOpenOption.APPEND)) {
out.append(s);
out.newLine();
}
}
Если мы используем Java 7 и выше, а также знаем, какой контент будет добавлен (добавлен) к файлу, мы можем использовать newBufferedWriter в пакете NIO.
public static void main(String[] args) {
Path FILE_PATH = Paths.get("C:/temp", "temp.txt");
String text = "\n Welcome to Java 8";
//Writing to the file temp.txt
try (BufferedWriter writer = Files.newBufferedWriter(FILE_PATH, StandardCharsets.UTF_8, StandardOpenOption.APPEND)) {
writer.write(text);
} catch (IOException e) {
e.printStackTrace();
}
}
Следует отметить несколько моментов:
- Всегда полезно указывать кодировку кодировки, и для этого у нас есть константа в классе
StandardCharsets
. - В коде используется оператор
try-with-resource
, в котором ресурсы автоматически закрываются после попытки.
Хотя OP не спрашивал, но на всякий случай мы хотим найти строки с определенным ключевым словом, например. confidential
мы можем использовать потоковые API в Java:
//Reading from the file the first line which contains word "confidential"
try {
Stream<String> lines = Files.lines(FILE_PATH);
Optional<String> containsJava = lines.filter(l->l.contains("confidential")).findFirst();
if(containsJava.isPresent()){
System.out.println(containsJava.get());
}
} catch (IOException e) {
e.printStackTrace();
}
write(String string)
, если ожидается новая строка после каждой записанной строки, следует вызвать newLine()
- person yongtw123; 26.06.2015
FileOutputStream fos = new FileOutputStream("File_Name", true);
fos.write(data);
true позволяет добавлять данные в существующий файл. Если мы напишем
FileOutputStream fos = new FileOutputStream("File_Name");
Он перезапишет существующий файл. Так что переходите к первому подходу.
FileOutputStream stream = new FileOutputStream(path, true);
try {
stream.write(
string.getBytes("UTF-8") // Choose your encoding.
);
} finally {
stream.close();
}
Затем перехватите IOException где-нибудь в восходящем направлении.
Создайте функцию в любом месте вашего проекта и просто вызывайте эту функцию, когда вам это нужно.
Ребята, вы должны помнить, что вы, ребята, вызываете активные потоки, которые вы не вызываете асинхронно, и, поскольку, вероятно, было бы неплохо от 5 до 10 страниц, чтобы все было сделано правильно. Почему бы не потратить больше времени на свой проект и забыть о написании того, что уже написано. Должным образом
//Adding a static modifier would make this accessible anywhere in your app
public Logger getLogger()
{
return java.util.logging.Logger.getLogger("MyLogFileName");
}
//call the method anywhere and append what you want to log
//Logger class will take care of putting timestamps for you
//plus the are ansychronously done so more of the
//processing power will go into your application
//from inside a function body in the same class ...{...
getLogger().log(Level.INFO,"the text you want to append");
...}...
/*********log file resides in server root log files********/
три строки кода, две действительно, поскольку третья фактически добавляет текст. :П
Библиотека
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
Код
public void append()
{
try
{
String path = "D:/sample.txt";
File file = new File(path);
FileWriter fileWriter = new FileWriter(file,true);
BufferedWriter bufferFileWriter = new BufferedWriter(fileWriter);
fileWriter.append("Sample text in the file to append");
bufferFileWriter.close();
System.out.println("User Registration Completed");
}catch(Exception ex)
{
System.out.println(ex);
}
}
Я мог бы предложить проект Apache Commons. Этот проект уже предоставляет основу для выполнения того, что вам нужно (т. Е. Гибкой фильтрации коллекций).
Следующий метод позволяет вам добавить текст в какой-либо файл:
private void appendToFile(String filePath, String text)
{
PrintWriter fileWriter = null;
try
{
fileWriter = new PrintWriter(new BufferedWriter(new FileWriter(
filePath, true)));
fileWriter.println(text);
} catch (IOException ioException)
{
ioException.printStackTrace();
} finally
{
if (fileWriter != null)
{
fileWriter.close();
}
}
}
В качестве альтернативы можно использовать FileUtils
:
public static void appendToFile(String filePath, String text) throws IOException
{
File file = new File(filePath);
if(!file.exists())
{
file.createNewFile();
}
String fileContents = FileUtils.readFileToString(file);
if(file.length() != 0)
{
fileContents = fileContents.concat(System.lineSeparator());
}
fileContents = fileContents.concat(text);
FileUtils.writeStringToFile(file, fileContents);
}
Это неэффективно, но работает нормально. Разрывы строк обрабатываются правильно, и создается новый файл, если он еще не существует.
Этот код удовлетворит ваши потребности:
FileWriter fw=new FileWriter("C:\\file.json",true);
fw.write("ssssss");
fw.close();
Если вы хотите ДОБАВИТЬ ТЕКСТ В ОПРЕДЕЛЕННЫХ СТРОКАХ, вы можете сначала прочитать весь файл, добавить текст в любом месте, а затем перезаписать все, как в приведенном ниже коде:
public static void addDatatoFile(String data1, String data2){
String fullPath = "/home/user/dir/file.csv";
File dir = new File(fullPath);
List<String> l = new LinkedList<String>();
try (BufferedReader br = new BufferedReader(new FileReader(dir))) {
String line;
int count = 0;
while ((line = br.readLine()) != null) {
if(count == 1){
//add data at the end of second line
line += data1;
}else if(count == 2){
//add other data at the end of third line
line += data2;
}
l.add(line);
count++;
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
createFileFromList(l, dir);
}
public static void createFileFromList(List<String> list, File f){
PrintWriter writer;
try {
writer = new PrintWriter(f, "UTF-8");
for (String d : list) {
writer.println(d.toString());
}
writer.close();
} catch (FileNotFoundException | UnsupportedEncodingException e) {
e.printStackTrace();
}
}
Мой ответ:
JFileChooser chooser= new JFileChooser();
chooser.showOpenDialog(chooser);
File file = chooser.getSelectedFile();
String Content = "What you want to append to file";
try
{
RandomAccessFile random = new RandomAccessFile(file, "rw");
long length = random.length();
random.setLength(length + 1);
random.seek(random.length());
random.writeBytes(Content);
random.close();
}
catch (Exception exception) {
//exception handling
}
Для версии JDK ›= 7
Вы можете использовать этот простой метод, который добавляет данное содержимое в указанный файл:
void appendToFile(String filePath, String content) {
try (FileWriter fw = new FileWriter(filePath, true)) {
fw.write(content + System.lineSeparator());
} catch (IOException e) {
// TODO handle exception
}
}
Мы создаем FileWriter в режиме добавления.
Вы можете использовать следующий код для добавления содержимого в файл:
String fileName="/home/shriram/Desktop/Images/"+"test.txt";
FileWriter fw=new FileWriter(fileName,true);
fw.write("here will be you content to insert or append in file");
fw.close();
FileWriter fw1=new FileWriter(fileName,true);
fw1.write("another content will be here to be append in the same file");
fw1.close();
1.7 Подход:
void appendToFile(String filePath, String content) throws IOException{
Path path = Paths.get(filePath);
try (BufferedWriter writer =
Files.newBufferedWriter(path,
StandardOpenOption.APPEND)) {
writer.newLine();
writer.append(content);
}
/*
//Alternative:
try (BufferedWriter bWriter =
Files.newBufferedWriter(path,
StandardOpenOption.WRITE, StandardOpenOption.APPEND);
PrintWriter pWriter = new PrintWriter(bWriter)
) {
pWriter.println();//to have println() style instead of newLine();
pWriter.append(content);//Also, bWriter.append(content);
}*/
}