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

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

当前回答

该代码将规范换行符,这可能是您真正想要做的,也可能不是。

这里有一个替代方案,它没有做到这一点,而且比NIO代码更容易理解(IMO)(尽管它仍然使用java.NIO.charset.charset):

public static String readFile(String file, String csName)
            throws IOException {
    Charset cs = Charset.forName(csName);
    return readFile(file, cs);
}

public static String readFile(String file, Charset cs)
            throws IOException {
    // No real need to close the BufferedReader/InputStreamReader
    // as they're only wrapping the stream
    FileInputStream stream = new FileInputStream(file);
    try {
        Reader reader = new BufferedReader(new InputStreamReader(stream, cs));
        StringBuilder builder = new StringBuilder();
        char[] buffer = new char[8192];
        int read;
        while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
            builder.append(buffer, 0, read);
        }
        return builder.toString();
    } finally {
        // Potential issue here: if this throws an IOException,
        // it will mask any others. Normally I'd use a utility
        // method which would log exceptions and swallow them
        stream.close();
    }        
}

其他回答

如果您正在寻找不涉及第三方库(例如Commons I/O)的替代方案,可以使用Scanner类:

private String readFile(String pathname) throws IOException {

    File file = new File(pathname);
    StringBuilder fileContents = new StringBuilder((int)file.length());        

    try (Scanner scanner = new Scanner(file)) {
        while(scanner.hasNextLine()) {
            fileContents.append(scanner.nextLine() + System.lineSeparator());
        }
        return fileContents.toString();
    }
}

使用JDK 8或更高版本:

未使用外部库

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

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

根据@erickson的回答,您可以使用:

public String readAll(String fileName) throws IOException {
    List<String> lines = Files.readAllLines(new File(fileName).toPath());
    return String.join("\n", lines.toArray(new String[lines.size()]));
}

Guava有一种类似于Willi aus Rohr提到的Commons IOUtils的方法:

import com.google.common.base.Charsets;
import com.google.common.io.Files;

// ...

String text = Files.toString(new File(path), Charsets.UTF_8);

由PiggyPiglet编辑文件#toString已弃用,将于2019年10月删除。而是使用Files.asCharSource(新文件(路径),StandardCharsets.UTF_8).read();

奥斯卡·雷耶斯编辑

这是引用库中的(简化)基础代码:

InputStream in = new FileInputStream(file);
byte[] b  = new byte[file.length()];
int len = b.length;
int total = 0;

while (total < len) {
  int result = in.read(b, total, len - total);
  if (result == -1) {
    break;
  }
  total += result;
}

return new String( b , Charsets.UTF_8 );

编辑(Jonik):以上内容与最近的Guava版本的源代码不匹配。有关当前源代码,请参阅com.google.common.io包中的类Files、CharStreams、ByteSource和CharSource。

此外,如果您的文件恰好位于jar中,您也可以使用此选项:

public String fromFileInJar(String path) {
    try ( Scanner scanner 
            = new Scanner(getClass().getResourceAsStream(path))) {
        return scanner.useDelimiter("\\A").next();
    }
}

例如,如果您的jar是

my.jar/com/some/thing/a.txt

然后你想这样调用它:

String myTxt = fromFileInJar("/com/com/thing/a.txt");