用Java创建和写入(文本)文件的最简单方法是什么?


当前回答

如果我们使用的是Java7及以上版本,并且还知道要添加(附加)到文件中的内容,我们可以使用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();
    }
}

有几点需要注意:

指定字符集编码总是一个好习惯,因此我们在类StandardCharset中有常量。代码使用try with resource语句,其中资源在try之后自动关闭。

虽然OP没有询问,但为了以防万一我们想搜索具有特定关键字的行,例如机密,我们可以使用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();
}

其他回答

最好的方法是使用Java7:Java7引入了一种处理文件系统的新方法,以及一个新的实用程序类—Files。使用Files类,我们还可以创建、移动、复制、删除文件和目录;它还可以用于读取和写入文件。

public void saveDataInFile(String data) throws IOException {
    Path path = Paths.get(fileName);
    byte[] strToBytes = data.getBytes();

    Files.write(path, strToBytes);
}

使用FileChannel写入如果您正在处理大型文件,FileChannel可以比标准IO更快。以下代码使用FileChannel将字符串写入文件:

public void saveDataInFile(String data) 
  throws IOException {
    RandomAccessFile stream = new RandomAccessFile(fileName, "rw");
    FileChannel channel = stream.getChannel();
    byte[] strBytes = data.getBytes();
    ByteBuffer buffer = ByteBuffer.allocate(strBytes.length);
    buffer.put(strBytes);
    buffer.flip();
    channel.write(buffer);
    stream.close();
    channel.close();
}

使用DataOutputStream写入

public void saveDataInFile(String data) throws IOException {
    FileOutputStream fos = new FileOutputStream(fileName);
    DataOutputStream outStream = new DataOutputStream(new BufferedOutputStream(fos));
    outStream.writeUTF(data);
    outStream.close();
}

使用FileOutputStream写入

现在让我们看看如何使用FileOutputStream将二进制数据写入文件。以下代码转换String int字节,并使用FileOutputStream将字节写入文件:

public void saveDataInFile(String data) throws IOException {
    FileOutputStream outputStream = new FileOutputStream(fileName);
    byte[] strToBytes = data.getBytes();
    outputStream.write(strToBytes);

    outputStream.close();
}

使用PrintWriter写入我们可以使用PrintWriter将格式化文本写入文件:

public void saveDataInFile() throws IOException {
    FileWriter fileWriter = new FileWriter(fileName);
    PrintWriter printWriter = new PrintWriter(fileWriter);
    printWriter.print("Some String");
    printWriter.printf("Product name is %s and its price is %d $", "iPhone", 1000);
    printWriter.close();
}

使用BufferedWriter写入:使用BufferedWriter将字符串写入新文件:

public void saveDataInFile(String data) throws IOException {
    BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
    writer.write(data);

    writer.close();
}

将字符串附加到现有文件:

public void saveDataInFile(String data) throws IOException {
    BufferedWriter writer = new BufferedWriter(new FileWriter(fileName, true));
    writer.append(' ');
    writer.append(data);

    writer.close();
}

请注意,下面的每个代码示例都可能引发IOException。为了简洁起见,省略了Try/catch/finally块。有关异常处理的信息,请参阅本教程。

请注意,如果文件已经存在,下面的每个代码示例都将覆盖该文件

创建文本文件:

PrintWriter writer = new PrintWriter("the-file-name.txt", "UTF-8");
writer.println("The first line");
writer.println("The second line");
writer.close();

创建二进制文件:

byte data[] = ...
FileOutputStream out = new FileOutputStream("the-file-name");
out.write(data);
out.close();

Java 7+用户可以使用Files类写入文件:

创建文本文件:

List<String> lines = Arrays.asList("The first line", "The second line");
Path file = Paths.get("the-file-name.txt");
Files.write(file, lines, StandardCharsets.UTF_8);
//Files.write(file, lines, StandardCharsets.UTF_8, StandardOpenOption.APPEND);

创建二进制文件:

byte data[] = ...
Path file = Paths.get("the-file-name");
Files.write(file, data);
//Files.write(file, data, StandardOpenOption.APPEND);

我能找到的最简单的方法是:

Path sampleOutputPath = Paths.get("/tmp/testfile")
try (BufferedWriter writer = Files.newBufferedWriter(sampleOutputPath)) {
    writer.write("Hello, world!");
}

它可能只适用于1.7+。

至少有几种方法可以创建文件并写入其中:

小文件(1.7)

您可以使用其中一种写入方法将字节或行写入文件。

Path file = Paths.get("path-to-file");
byte[] buf = "text-to-write-to-file".getBytes();
Files.write(file, buf);

这些方法为您处理大部分工作,例如打开和关闭流,但不适用于处理大型文件。

使用缓冲流I/O写入更大的文件(1.7)

java.nio.file包支持通道I/O,它可以在缓冲区中移动数据,绕过一些可能阻塞流I/O的层。

String s = "much-larger-text-to-write-to-file";
try (BufferedWriter writer = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) {
    writer.write(s, 0, s.length());
}

这种方法由于其高效的性能,特别是在完成大量写入操作时,是优先的。缓冲操作具有这种效果,因为它们不需要为每个字节调用操作系统的写入方法,从而减少了昂贵的I/O操作。

使用NIOAPI复制(并创建一个新的)带有输出流的文件(1.7)

Path oldFile = Paths.get("existing-file-path");
Path newFile = Paths.get("new-file-path");
try (OutputStream os = new FileOutputStream(newFile.toFile())) {
    Files.copy(oldFile, os);
}

还有其他方法允许将输入流中的所有字节复制到文件中。

FileWriter(文本)(<1.7)

直接写入文件(性能较低),仅当写入次数较少时才应使用。用于将面向字符的数据写入文件。

String s= "some-text";
FileWriter fileWriter = new FileWriter("C:\\path\\to\\file\\file.txt");
fileWriter.write(fileContent);
fileWriter.close();

FileOutputStream(二进制)(<1.7)

FileOutputStream用于写入原始字节流,如图像数据。

byte data[] = "binary-to-write-to-file".getBytes();
FileOutputStream out = new FileOutputStream("file-name");
out.write(data);
out.close();

使用这种方法,应该考虑始终写入字节数组,而不是一次写入一个字节。加速可能非常显著-高达10倍或更高。因此,建议尽可能使用write(byte[])方法。

要创建文件而不覆盖现有文件,请执行以下操作:

System.out.println("Choose folder to create file");
JFileChooser c = new JFileChooser();
c.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
c.showOpenDialog(c);
c.getSelectedFile();
f = c.getSelectedFile(); // File f - global variable
String newfile = f + "\\hi.doc";//.txt or .doc or .html
File file = new File(newfile);

try {
    //System.out.println(f);
    boolean flag = file.createNewFile();

    if(flag == true) {
        JOptionPane.showMessageDialog(rootPane, "File created successfully");
    }
    else {
        JOptionPane.showMessageDialog(rootPane, "File already exists");
    }
    /* Or use exists() function as follows:
        if(file.exists() == true) {
            JOptionPane.showMessageDialog(rootPane, "File already exists");
        }
        else {
            JOptionPane.showMessageDialog(rootPane, "File created successfully");
        }
    */
}
catch(Exception e) {
    // Any exception handling method of your choice
}