我已经用下面这个成语有一段时间了。这似乎是传播最广的,至少在我访问过的网站上。

在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();
    }
}

当前回答

如果您需要字符串处理(并行处理),Java8有很棒的StreamAPI。

String result = Files.lines(Paths.get("file.txt"))
                    .parallel() // for parallel processing 
                    .map(String::trim) // to change line   
                    .filter(line -> line.length() > 2) // to filter some lines by a predicate                        
                    .collect(Collectors.joining()); // to join lines

JDK示例samples/lambda/BulkDataOperations中提供了更多示例,可以从Oracle Java SE 8下载页面下载

另一个单线示例

String out = String.join("\n", Files.readAllLines(Paths.get("file.txt")));

其他回答

import java.nio.file.Files;

.......

 String readFile(String filename) {
            File f = new File(filename);
            try {
                byte[] bytes = Files.readAllBytes(f.toPath());
                return new String(bytes,"UTF-8");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
    }

使用JDK 8或更高版本:

未使用外部库

您可以从文件内容创建一个新的String对象(使用java.nio.file包中的类):

public String readStringFromFile(String filePath) throws IOException {
    String fileContent = new String(Files.readAllBytes(Paths.get(filePath)));
    return fileContent;
}

读取文件中的所有文本

Java 11添加了readString()方法,将小文件作为字符串读取,保留了行终止符:

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);
}

从文件中读取文本行

Java7添加了一种方便的方法,以文本行形式读取文件,表示为List<String>。这种方法是“有损的”,因为行分隔符是从每行的末尾剥离的。

List<String> lines = Files.readAllLines(Paths.get(path), encoding);

Java8添加了Files.line()方法来生成Stream<String>。同样,这种方法是有损耗的,因为行分隔符被剥离了。如果在读取文件时遇到IOException,它将被包装在UncheckedIOException中,因为Stream不接受引发选中异常的lambda。

try (Stream<String> lines = Files.lines(path, encoding)) {
  lines.forEach(System.out::println);
}

此流确实需要close()调用;这在API中记录得很差,我怀疑很多人甚至没有注意到Stream有一个close()方法。确保使用如图所示的ARM块。

如果使用的是文件以外的源,则可以改用BufferedReader中的lines()方法。

内存利用率

如果文件相对于可用内存足够小,那么一次读取整个文件可能会很好。但是,如果文件太大,一次读取一行,处理它,然后在继续下一行之前丢弃它可能是更好的方法。以这种方式进行流处理可以消除作为内存需求因素的总文件大小。

字符编码

原始文章中的示例缺少的一点是字符编码。这种编码通常无法从文件本身确定,并且需要元数据(如HTTP头)来传递这一重要信息。

StandardCharsets类为所有Java运行时所需的编码定义了一些常量:

String content = readFile("test.txt", StandardCharsets.UTF_8);

平台默认值可从Charset类本身获得:

String content = readFile("test.txt", Charset.defaultCharset());

在某些特殊情况下,平台默认值是您想要的,但这种情况很少见。您应该能够证明您的选择是合理的,因为平台默认值是不可移植的。一个可能正确的例子是读取标准输入或写入标准输出时。


注意:这个答案很大程度上取代了我的Java6版本。Java7的实用程序安全地简化了代码,旧的答案使用了映射字节缓冲区,在映射缓冲区被垃圾收集之前,可以防止读取的文件被删除。您可以通过此答案上的“编辑”链接查看旧版本。

在java8中,有一个新类

java.util.stream.stream流

流表示一系列元素,并支持对这些元素执行计算的不同类型的操作

阅读更多信息:

Oracle文档

这里有一个例子:

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

public Class ReadFile{
  public  static String readFile(String filePath) {
 StringBuilder  stringBuilder = new StringBuilder();
    String ls = System.getProperty("line.separator");
        try {

            try (Stream<String> lines = Files.lines(Paths.get(filePath), StandardCharsets.UTF_8)) {
                for (String line : (Iterable<String>) lines::iterator) {


                      stringBuilder.append(line);
                      stringBuilder.append(ls);


                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

      return stringBuilder.toString(); 


}

}

在扫描程序后按Ctrl+F键,我认为也应该列出扫描程序解决方案。最容易阅读的方式如下:

public String fileToString(File file, Charset charset) {
  Scanner fileReader = new Scanner(file, charset);
  fileReader.useDelimiter("\\Z"); // \Z means EOF.
  String out = fileReader.next();
  fileReader.close();
  return out;
}

如果您使用Java 7或更高版本(您确实应该),请考虑使用try with资源,以使代码更易于阅读。不要再把任何东西乱丢了。但我认为这主要是一种文体选择。

我发布这篇文章主要是为了完成主义,因为如果您需要经常这样做,java.nio.file.file中应该有一些东西可以更好地完成这项工作。

我的建议是使用File#readAllBytes(Path)获取所有字节,并将其输入到新的String(byte[]字符集)中,以从中获取一个您可以信任的String。在你的一生中,Charset会对你很刻薄,所以现在就要小心这些东西。

其他人已经给出了代码和东西,我不想抢走他们的荣耀