如何将文本附加到Java中的现有文件中

fly*_*ina 660 java io file-io text-files

我需要将文本重复附加到Java中的现有文件中.我怎么做?

Kip*_*Kip 770

你这样做是为了记录目的吗?如果是这样,那么有几个库.最受欢迎的两个是Log4jLogback.

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
}
Run Code Online (Sandbox Code Playgroud)

小心:NoSuchFileException如果文件尚不存在,上述方法将抛出一个.它也不会自动附加换行符(当您追加到文本文件时通常需要它).Steve Chambers的答案涵盖了如何在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
}
Run Code Online (Sandbox Code Playgroud)

笔记:

  • FileWriter构造函数的第二个参数将告诉它附加到文件,而不是写一个新文件.(如果该文件不存在,则会创建该文件.)
  • BufferedWriter对于昂贵的作家(例如FileWriter),建议使用a .
  • 使用a PrintWriter可以访问println您可能习惯的语法System.out.
  • BufferedWriterPrintWriter包装是不是绝对必要的.

旧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
}
Run Code Online (Sandbox Code Playgroud)

异常处理

如果您需要针对较旧的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
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 您应该使用java7 try-with-resources或将close()放在finally块中,以确保在异常的情况下关闭该文件 (31认同)
  • 注意,如果在try块内抛出异常,"较旧的java"示例将无法正确关闭流. (5认同)
  • 让我们想象一下`new BufferedWriter(...)`抛出一个异常; `FileWriter`会被关闭吗?我猜它不会被关闭,因为`close()`方法(在正常条件下)将在`out`对象上调用,在这种情况下int不会被初始化 - 所以实际上是`close()`方法不会被调用 - >文件将被打开,但不会被关闭.所以IMHO的`try`语句应该看起来像这样`try(FileWriter fw = new FileWriter("myFile.txt")){Print writer = new .... // code goes here}`他应该`flush() `作者在退出`try`块之前!!! (3认同)
  • Java 7 方法的一些可能的“陷阱”:(1) 如果文件尚不存在,`StandardOpenOption.APPEND` 将不会创建它 - 有点像静默失败,因为它不会抛出异常任何一个。(2) 使用 `.getBytes()` 将意味着附加文本之前或之后没有返回字符。添加了[替代答案](/sf/ask/113766411/#44301865)来解决这些问题。 (2认同)

nor*_*ole 162

您可以使用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());
}
Run Code Online (Sandbox Code Playgroud)

  • 如果在[@etech的答案](http://stackoverflow.com/a/15053443/1393766)中显示,`close`应放在`finally`块中,以防在创建FileWriter和调用close之间抛出异常. (9认同)
  • 很好的答案,虽然最好将System.getProperty("line.separator")用于新行而不是"\n". (5认同)
  • 尝试资源怎么样?```try(FileWriter fw = new FileWriter(filename,true)){ // 随便 }catch(IOException ex){ ex.printStackTrace(); }``` (2认同)

ete*_*ech 69

不应该使用try/catch块的所有答案都包含finally块中的.close()块吗?

标记答案的示例:

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();
    }
} 
Run Code Online (Sandbox Code Playgroud)

此外,从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);
}
Run Code Online (Sandbox Code Playgroud)

  • @Kip 不,超出范围在 Java 中没有任何作用。该文件将在未来的某个随机时间关闭。(可能是当程序关闭时) (2认同)

rip*_*234 42

编辑 - 从Apache Commons 2.1开始,正确的方法是:

FileUtils.writeStringToFile(file, "String to append", true);
Run Code Online (Sandbox Code Playgroud)

我改编了@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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 哦谢谢.我对所有其他答案的复杂性感到好笑.我真的不明白为什么人们喜欢让他们(开发者)的生活复杂化. (4认同)
  • 这种方法的问题在于它每次都打开和关闭输出流。根据您写入文件的内容和频率,这可能会导致可笑的开销。 (3认同)

Ste*_*ers 28

为了略微扩展Kip的答案,这里有一个简单的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...
}
Run Code Online (Sandbox Code Playgroud)

注意:上面使用了Files.write将文本写入文件的重载(即类似于println命令).要将文本写到最后(即类似于print命令),Files.write可以使用替代重载,传入字节数组(例如"mytext".getBytes(StandardCharsets.UTF_8)).


Emi*_* L. 21

确保在所有方案中正确关闭流.

令人担忧的是,如果出现错误,这些答案中有多少会使文件句柄保持打开状态.答案/sf/answers/1053741041/是钱,但只是因为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
     }
  }
Run Code Online (Sandbox Code Playgroud)

编辑:

从Java 7开始,推荐的方法是使用"try with resources"并让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.
  }
Run Code Online (Sandbox Code Playgroud)


Tso*_*yan 13

在Java-7中它也可以这样做:

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
Run Code Online (Sandbox Code Playgroud)

// ---------------------

Path filePath = Paths.get("someFile.txt");
if (!Files.exists(filePath)) {
    Files.createFile(filePath);
}
Files.write(filePath, "Text to be added".getBytes(), StandardOpenOption.APPEND);
Run Code Online (Sandbox Code Playgroud)

  • 需要什么进口商品?这些东西使用哪个库? (2认同)

Lef*_*Bab 9

java 7+

在我的拙见中,因为我是普通java的粉丝,我建议它是上述答案的组合.也许我迟到了.这是代码:

 String sampleText = "test" +  System.getProperty("line.separator");
 Files.write(Paths.get(filePath), sampleText.getBytes(StandardCharsets.UTF_8), 
 StandardOpenOption.CREATE, StandardOpenOption.APPEND);
Run Code Online (Sandbox Code Playgroud)

如果该文件不存在,则创建该文件,如果该文件已存在,则将sampleText附加 到现有文件.使用它,可以避免在类路径中添加不必要的库.


Fli*_*Off 7

这可以在一行代码中完成.希望这可以帮助 :)

Files.write(Paths.get(fileName), msg.getBytes(), StandardOpenOption.APPEND);
Run Code Online (Sandbox Code Playgroud)

  • 它可能还不够:) 更好的版本是 Files.write(Paths.get(fileName), msg.getBytes(), StandardOpenOption.APPEND, StandardOpenOption.CREATE); (2认同)

ica*_*dri 6

使用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();
Run Code Online (Sandbox Code Playgroud)

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

StandardOpenOption此代码中使用的参数:打开要写入的文件,仅附加到文件,如果文件不存在则创建该文件.

Paths.get("path here")可以替换为new File("path here").toPath().并且Charset.forName("charset name")可以进行修改以适应所需的Charset.


xhu*_*dik 5

我只是添加小细节:

    new FileWriter("outfilename", true)
Run Code Online (Sandbox Code Playgroud)

2.nd参数(真)是一个功能(或接口)称为追加(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进程添加一些内容


dan*_*uch 5

样品,使用番石榴:

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个可怕的建议.您打开文件流42次而不是一次. (12认同)
  • @xehpuk好吧,这取决于.如果它使代码更具可读性,那么42仍然可以.42k是不可接受的. (3认同)