我需要在Java中反复向现有文件追加文本。我怎么做呢?


当前回答

下面的方法可以让你把文本添加到文件中:

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);
}

它效率不高,但运行良好。换行符被正确处理,如果还不存在换行符,则创建一个新文件。

其他回答

稍微扩展一下基普的回答, 下面是一个简单的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...
}

进一步指出:

The above uses the Files.write overload that writes lines of text to a file (i.e. similar to a println command). To just write text to the end (i.e. similar to a print command), an alternative Files.write overload can be used, passing in a byte array (e.g. "mytext".getBytes(StandardCharsets.UTF_8)). The CREATE option will only work if the specified directory already exists - if it doesn't, a NoSuchFileException is thrown. If required, the following code could be added after setting path to create the directory structure: Path pathParent = path.getParent(); if (!Files.exists(pathParent)) { Files.createDirectories(pathParent); }

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);
    }*/
}

您这样做是为了记录日志吗?如果是这样,有几个库。其中最流行的两个是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。它也不会自动追加换行符(当追加到文本文件时,您经常希望这样)。另一种方法是同时传递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可以访问您可能在System.out中习惯的println语法。 但是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
    }
}

您可以使用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());
}

使用java.nio.Files和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();

这将使用Files创建一个BufferedWriter,它接受StandardOpenOption参数,并从结果BufferedWriter创建一个自动刷新的PrintWriter。然后可以调用PrintWriter的println()方法来写入文件。

这段代码中使用的StandardOpenOption参数:打开文件进行写入,仅追加到文件中,并在文件不存在时创建文件。

路径。get("path here")可以用new File("path here"). topath()代替。 和字符集。forName(“字符集名称”)可以修改以适应所需的字符集。