我使用下面的成语已经有一段时间了。而且它似乎是最广泛的,至少在我访问过的网站上是这样。
有没有更好/不同的方式在 Java 中将文件读入字符串?
private String readFile(String file) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader (file));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
try {
while((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append(ls);
}
return stringBuilder.toString();
} finally {
reader.close();
}
}
最佳答案
从文件中读取所有文本
Java 11 添加了 readString()将小文件读取为 String
的方法, 保留行终止符:
String content = Files.readString(path, encoding);
对于 Java 7 和 11 之间的版本,这里有一个紧凑、健壮的习惯用法,包含在一个实用方法中:
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
从文件中读取文本行
Java 7 添加了 convenience method to read a file as lines of text,表示为 List<String>
.这种方法是“有损的”,因为行分隔符从每行的末尾被剥离。
List<String> lines = Files.readAllLines(Paths.get(path), encoding);
Java 8 添加了 Files.lines()
产生 Stream<String>
的方法.同样,这种方法是有损的,因为行分隔符被剥离。如果 IOException
在读取文件时遇到,它被包裹在 UncheckedIOException
中, 自 Stream
不接受抛出已检查异常的 lambda。
try (Stream<String> lines = Files.lines(path, encoding)) {
lines.forEach(System.out::println);
}
这个 Stream
确实需要 close()
称呼;这在 API 上的记录很差,我怀疑很多人甚至没有注意到 Stream
有一个 close()
方法。请务必使用如图所示的 ARM block 。
如果您使用的不是文件源,您可以使用 lines()
BufferedReader
中的方法而是。
内存利用率
如果您的文件相对于可用内存足够小,则一次读取整个文件可能会正常工作。但是,如果您的文件太大,一次读取一行,处理它,然后在继续下一个之前丢弃它可能是更好的方法。以这种方式进行流处理可以消除总文件大小作为内存需求的一个因素。
字符编码
原始帖子的示例中缺少的一件事是字符编码。这种编码通常无法从文件本身确定,并且需要诸如 HTTP header 之类的元数据来传达此重要信息。
StandardCharsets
类为所有 Java 运行时所需的编码定义了一些常量:
String content = readFile("test.txt", StandardCharsets.UTF_8);
平台默认值可从 the Charset
class 获得本身:
String content = readFile("test.txt", Charset.defaultCharset());
在某些特殊情况下,平台默认值是您想要的,但这种情况很少见。您应该能够证明您的选择是合理的,因为平台默认值是不可移植的。一个可能正确的例子是读取标准输入或写入标准输出时。
注意:这个答案在很大程度上取代了我的 Java 6 版本。 Java 7 的实用程序安全地简化了代码,并且使用映射字节缓冲区的旧答案阻止了读取的文件被删除,直到映射缓冲区被垃圾收集。您可以通过此答案的“已编辑”链接查看旧版本。
关于java - 如何从文件内容创建 Java 字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/326390/