java - 如何从文件内容创建 Java 字符串?

标签 java string file file-io io

我使用下面的成语已经有一段时间了。而且它似乎是最广泛的,至少在我访问过的网站上是这样。

有没有更好/不同的方式在 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/

相关文章:

java - 如何在 Android 中旋转 Rect 对象

java - 外部变量不可用内部增强

javascript - 如何为以@开头或以,结尾的字符串匹配编写正则表达式?

c - C 相等运算符是否比较两个字符串的字面值或其内存位置?

c# - 将float数组写入二进制文件c#

java - 编写具有搜索功能的java缓存管理器

java - android 无法在 Play 商店中找到应用名称

编译错误 - 从文件中读入

java - 在哪里可以看到我在工作区中创建的新文件?

c++ - 有人可以帮助阐明头文件的工作原理吗?