在Java中,似乎有不同的方式来读取和写入文件数据。

我想从一个文件读取ASCII数据。可能的方式和它们的区别是什么?


当前回答

Java 11 Files.readString中引入了最直观的方法

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String args[]) throws IOException {
        String content = Files.readString(Paths.get("D:\\sandbox\\mvn\\my-app\\my-app.iml"));
        System.out.print(content);
    }
}

PHP几十年来一直享有这种特权!☺

其他回答

我最喜欢的读取小文件的方法是使用BufferedReader和StringBuilder。它非常简单和切中要害(虽然不是特别有效,但对大多数情况来说已经足够好了):

BufferedReader br = new BufferedReader(new FileReader("file.txt"));
try {
    StringBuilder sb = new StringBuilder();
    String line = br.readLine();

    while (line != null) {
        sb.append(line);
        sb.append(System.lineSeparator());
        line = br.readLine();
    }
    String everything = sb.toString();
} finally {
    br.close();
}

有人指出,在Java 7之后,你应该使用try-with-resources(即自动关闭)功能:

try(BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    StringBuilder sb = new StringBuilder();
    String line = br.readLine();

    while (line != null) {
        sb.append(line);
        sb.append(System.lineSeparator());
        line = br.readLine();
    }
    String everything = sb.toString();
}

当我读取这样的字符串时,我通常希望每行都做一些字符串处理,所以我选择了这个实现。

虽然如果我只是想将文件读入字符串,我总是使用Apache Commons IO和类IOUtils.toString()方法。你可以在这里查看源代码:

http://www.docjar.com/html/api/org/apache/commons/io/IOUtils.java.html

FileInputStream inputStream = new FileInputStream("foo.txt");
try {
    String everything = IOUtils.toString(inputStream);
} finally {
    inputStream.close();
}

在Java 7中甚至更简单:

try(FileInputStream inputStream = new FileInputStream("foo.txt")) {     
    String everything = IOUtils.toString(inputStream);
    // do something with everything string
}

ASCII是一个文本文件,因此您可以使用reader进行读取。Java还支持使用InputStreams从二进制文件中读取。如果要读取的文件很大,那么您可能希望在FileReader之上使用BufferedReader来提高读取性能。

阅读这篇关于如何使用Reader的文章

我还推荐你下载并阅读这本很棒(但免费)的书,叫做《用Java思考》

在Java 7中:

new String(Files.readAllBytes(...))

(文档) 或

Files.readAllLines(...)

(文档)

在Java 8中:

Files.lines(..).forEach(...)

(文档)

try (Stream<String> stream = Files.lines(Paths.get(String.valueOf(new File("yourFile.txt"))))) {
    stream.forEach(System.out::println);
} catch (IOException e) {
    e.printStackTrace();
}

新文件(< path_name >)

通过将给定的路径名字符串转换为抽象路径名来创建一个新的File实例。如果给定的字符串是空字符串,那么结果就是空的抽象路径名。 参数: pathname -路径名字符串 抛出: NullPointerException -如果路径名参数为空

文件。lines返回String流

Stream<String> Stream = Files.lines(路径。get(字符串。返回对象的值(新文件(“yourFile.txt”)))) 可以抛出nullpointerexction, FileNotFoundException,所以,保持它在尝试将照顾异常在运行时

stream.forEach(System.out::println);

这用于在控制台中迭代流和打印 如果您有不同的用例,您可以提供您的自定义函数来操作行流

你可以使用readAllLines和join方法在一行中获取整个文件内容:

String str = String.join("\n",Files.readAllLines(Paths.get("e:\\text.txt")));

它默认使用UTF-8编码,可以正确读取ASCII数据。

你也可以使用readAllBytes:

String str = new String(Files.readAllBytes(Paths.get("e:\\text.txt")), StandardCharsets.UTF_8);

我认为readAllBytes更快更精确,因为它不会用\n替换新行,也不会用\r\n替换新行。哪一种合适取决于你的需要。

在实践中,缓冲流类的性能要高得多,以至于NIO.2 API包含了专门返回这些流类的方法,部分原因是为了鼓励您始终在应用程序中使用缓冲流。

这里有一个例子:

Path path = Paths.get("/myfolder/myfile.ext");
try (BufferedReader reader = Files.newBufferedReader(path)) {
    // Read from the stream
    String currentLine = null;
    while ((currentLine = reader.readLine()) != null)
        //do your code here
} catch (IOException e) {
    // Handle file I/O exception...
}

您可以替换此代码

BufferedReader reader = Files.newBufferedReader(path);

BufferedReader br = new BufferedReader(new FileReader("/myfolder/myfile.ext"));

我推荐这篇文章来学习Java NIO和IO的主要用途。