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


当前回答

最好使用try-with-resources,而不是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();
    }
}

其他回答

您这样做是为了记录日志吗?如果是这样,有几个库。其中最流行的两个是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
    }
}
    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();         
    }

这将达到你的目的。

对于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对象。

在项目的任何地方创建一个函数,并在任何需要的地方简单地调用该函数。

伙计们,你们要记住,你们调用的是活动线程,而不是异步调用,因为它可能需要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********/

三行代码,实际上是两行,因为第三行实际上是追加文本。: P

如果我们使用Java 7及以上版本,并且也知道要添加(追加)到文件的内容,我们可以使用NIO包中的newBufferedWriter方法。

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语句,其中资源在try之后自动关闭。

虽然OP没有要求,但以防我们想要搜索具有特定关键字的行,例如confidential,我们可以在Java中使用流api:

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