Как добавить текст в существующий файл в Java - PullRequest
642 голосов
/ 26 октября 2009

Мне нужно несколько раз добавлять текст в существующий файл на Java. Как мне это сделать?

Ответы [ 30 ]

746 голосов
/ 26 октября 2009

Вы делаете это для целей регистрации? В этом случае несколько библиотек для этого . Двумя наиболее популярными являются Log4j и Logback .

Java 7 +

Если вам просто нужно сделать это один раз, класс Files делает это легко:

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, если файл еще не существует. Он также не добавляет новую строку автоматически (что часто требуется при добавлении в текстовый файл). Ответ Стива Чамберса описывает, как это можно сделать с помощью Files класса.

Однако, если вы будете записывать в один и тот же файл много раз, описанное выше должно многократно открывать и закрывать файл на диске, что является медленной операцией. В этом случае буферизованный писатель лучше:

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 скажет ему добавить файл, а не записывать новый файл. (Если файл не существует, он будет создан.)
  • Использование BufferedWriter рекомендуется для дорогого писателя (например, FileWriter).
  • Использование 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
    }
}
158 голосов
/ 26 октября 2009

Вы можете использовать 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());
}
67 голосов
/ 24 февраля 2013

Разве все ответы здесь с блоками 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);
}
40 голосов
/ 03 декабря 2010

Редактировать - по состоянию на Apache Commons 2.1, правильный способ сделать это:

FileUtils.writeStringToFile(file, "String to append", true);

Я адаптировал решение @ Kip для корректного закрытия файла:

public static void appendToFile(String targetFile, String s) throws IOException {
    appendToFile(new File(targetFile), s);
}

public static void appendToFile(File targetFile, String s) throws IOException {
    PrintWriter out = null;
    try {
        out = new PrintWriter(new BufferedWriter(new FileWriter(targetFile, true)));
        out.println(s);
    } finally {
        if (out != null) {
            out.close();
        }
    }
}

25 голосов
/ 01 июня 2017

Чтобы немного расширить ответ Кипа , Вот простой метод 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...
}

Примечание: Выше используется перегрузка Files.write, которая записывает строк текста в файл (т. Е. Аналогична команде println). Чтобы просто записать текст в конец (т. Е. Аналогично команде print), можно использовать альтернативную перегрузку Files.write, передав байтовый массив (например, "mytext".getBytes(StandardCharsets.UTF_8)).

21 голосов
/ 11 сентября 2013

Убедитесь, что поток правильно закрыт во всех сценариях.

Немного настораживает, сколько из этих ответов оставляют дескриптор файла открытым в случае ошибки. Ответ 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
     }
  }

Edit:

Начиная с 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.
  }
13 голосов
/ 05 апреля 2015

В 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);
9 голосов
/ 09 февраля 2018

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 в существующий файл. Использование этого избавит вас от добавления ненужных библиотек в ваш путь к классам.

7 голосов
/ 06 августа 2015

Это можно сделать одной строкой кода. Надеюсь, это поможет:)

Files.write(Paths.get(fileName), msg.getBytes(), StandardOpenOption.APPEND);
6 голосов
/ 20 июля 2013

Использование 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 с использованием файлов, который принимает параметры StandardOpenOption, и автоматическую очистку PrintWriter из результирующего BufferedWriter. PrintWriter 'println() метод, затем может быть вызван для записи в файл.

Параметры StandardOpenOption, используемые в этом коде: открывает файл для записи, только добавляет его в файл и создает файл, если он не существует.

Paths.get("path here") можно заменить на new File("path here").toPath(). И Charset.forName("charset name") можно изменить, чтобы приспособить к желаемому Charset.

...