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

如何从文件内容创建Java字符串?,java,string,file,file-io,io,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

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

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

如果您愿意使用外部库,请查看(200KB JAR)。它包含一种方法,允许您使用一行代码将整个
文件
读入
字符串

例如:

import java.io.*;
导入java.nio.charset.*;
导入org.apache.commons.io.*;
公共字符串readFile()引发IOException{
File File=新文件(“data.txt”);
返回FileUtils.readFileToString(文件,StandardCharsets.UTF_8);
}

Java试图在所有方面都非常通用和灵活。因此,脚本语言中相对简单的东西(您的代码将被python中的“
open(file).read()
”替换)要复杂得多。除了使用外部库(如前面提到的)之外,似乎没有任何更短的方法来实现这一点。您的选择:

  • 使用外部库
  • 将此代码复制到所有项目中
  • 创建您自己的迷你库,其中包含您经常使用的函数
您的最佳选择可能是第二个,因为它具有最少的依赖性。

读取文件中的所有文本 Java 11添加了将小文件作为
字符串读取的方法,保留了行终止符:

String content = Files.readString(path, StandardCharsets.US_ASCII);
对于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> lines = Files.readAllLines(Paths.get(path), encoding);
确实需要调用;这在API中的文档记录得很差,我怀疑很多人甚至没有注意到
Stream
有一个
close()
方法。确保使用如图所示的臂块

如果您使用的是非文件源,则可以使用
BufferedReader
中的方法

内存利用率 保留换行符的第一种方法可能暂时需要几倍于文件大小的内存,因为在短时间内,原始文件内容(字节数组)和解码字符(即使文件中编码为8位,每个字符都是16位)同时驻留在内存中。应用于已知相对于可用内存较小的文件是最安全的

第二种方法是读取行,通常内存效率更高,因为用于解码的输入字节缓冲区不需要包含整个文件。但是,它仍然不适用于相对于可用内存非常大的文件

对于读取大文件,您的程序需要不同的设计,即从流中读取文本块,对其进行处理,然后转到下一个,重用相同的固定大小内存块。这里的“大”取决于计算机规格。如今,这个阈值可能是许多GB的RAM。第三种方法是使用
,如果您的输入“记录”恰好是单独的行,则可以这样做。(使用
BufferedReader
readLine()
方法与此方法在程序上是等效的。)

字符编码 原始帖子中的示例缺少的一点是字符编码。在某些特殊情况下,平台默认值是您想要的,但它们很少,您应该能够证明您的选择是正确的

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

String content = readFile("test.txt", StandardCharsets.UTF_8);
平台默认值可从自身获得:



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

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


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

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


同一主题上有一个变体,它使用for循环而不是while循环来限制line变量的范围。是否“更好”是个人品味的问题

for(String line = reader.readLine(); line != null; line = reader.readLine()) {
    stringBuilder.append(line);
    stringBuilder.append(ls);
}
其方法与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);
通过Piggypeglet编辑
文件#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 );
InputStream in=新文件InputStream(文件);
byte[]b=新字节[file.length()];
int len=b.长度;
int-total=0;
while(总计

编辑(由Jonik编写):上面的代码与最近的Guava版本的源代码不匹配。有关当前源代码,请参阅包中的类和。

以二进制形式读取文件并在末尾进行转换

public static String readFileAsString(String filePath) throws IOException {
    DataInputStream dis = new DataInputStream(new FileInputStream(filePath));
    try {
        long len = new File(filePath).length();
        if (len > Integer.MAX_VALUE) throw new IOException("File "+filePath+" too large, was "+len+" bytes.");
        byte[] bytes = new byte[(int) len];
        dis.readFully(bytes);
        return new String(bytes, "UTF-8");
    } finally {
        dis.close();
    }
}

基于以下内容的非常精简的解决方案:

或者,如果要设置字符集:

Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block
或者,使用一个块,它将为您调用
scanner.close()

try (Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" )) {
    String text = scanner.useDelimiter("\\A").next();
}
请记住,
扫描器
构造函数可以抛出一个
IOException
。不要忘记导入
java.io
java.util


来源:

如果是文本文件,为什么不使用?
import com.google.common.base.Charsets;
import com.google.common.io.Files;

// ...

String text = Files.toString(new File(path), Charsets.UTF_8);
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 );
public static String readFileAsString(String filePath) throws IOException {
    DataInputStream dis = new DataInputStream(new FileInputStream(filePath));
    try {
        long len = new File(filePath).length();
        if (len > Integer.MAX_VALUE) throw new IOException("File "+filePath+" too large, was "+len+" bytes.");
        byte[] bytes = new byte[(int) len];
        dis.readFully(bytes);
        return new String(bytes, "UTF-8");
    } finally {
        dis.close();
    }
}
Scanner scanner = new Scanner( new File("poem.txt") );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block
Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block
try (Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" )) {
    String text = scanner.useDelimiter("\\A").next();
}
public static String readFileToString(File file) throws IOException
public static List<String> readLines(File file) throws IOException
public static String readFileContent(String filename, Charset charset) throws IOException {
    RandomAccessFile raf = null;
    try {
        raf = new RandomAccessFile(filename, "r");
        byte[] buffer = new byte[(int)raf.length()];
        raf.readFully(buffer);
        return new String(buffer, charset);
    } finally {
        closeStream(raf);
    }
} 


private static void closeStream(Closeable c) {
    if (c != null) {
        try {
            c.close();
        } catch (IOException ex) {
            // do nothing
        }
    }
}
Reader input = new FileReader();
StringWriter output = new StringWriter();
try {
  IOUtils.copy(input, output);
} finally {
  input.close();
}
String fileContents = output.toString();
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 "";
    }
public String readStringFromInputStream(FileInputStream fileInputStream) {
    StringBuffer stringBuffer = new StringBuffer();
    try {
        byte[] buffer;
        while (fileInputStream.available() > 0) {
            buffer = new byte[fileInputStream.available()];
            fileInputStream.read(buffer);
            stringBuffer.append(new String(buffer, "ISO-8859-1"));
        }
    } catch (FileNotFoundException e) {
    } catch (IOException e) { }
    return stringBuffer.toString();
}
private String readFile(String pathname) throws IOException {

File file = new File(pathname);
StringBuilder fileContents = new StringBuilder((int)file.length());
Scanner scanner = new Scanner(file);
String lineSeparator = System.getProperty("line.separator");

try {
    while(scanner.hasNextLine()) {        
        fileContents.append(scanner.nextLine() + lineSeparator);
    }
    return fileContents.toString();
} finally {
    scanner.close();
}
}
    private String readFile(String pathname) throws IOException {
    File file = new File(pathname);
    StringBuilder fileContents = new StringBuilder((int) file.length());
    Scanner scanner = new Scanner(new BufferedReader(new FileReader(file)));
    String lineSeparator = System.getProperty("line.separator");

    try {
        if (scanner.hasNextLine()) {
            fileContents.append(scanner.nextLine());
        }
        while (scanner.hasNextLine()) {
            fileContents.append(lineSeparator + scanner.nextLine());
        }
        return fileContents.toString();
    } finally {
        scanner.close();
    }
}
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
String out = String.join("\n", Files.readAllLines(Paths.get("file.txt")));
static String readFile(File file, String charset)
        throws IOException
{
    FileInputStream fileInputStream = new FileInputStream(file);
    byte[] buffer = new byte[fileInputStream.available()];
    int length = fileInputStream.read(buffer);
    fileInputStream.close();
    return new String(buffer, 0, length, charset);
}
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;
}
String content = new String(Files.readAllBytes(Paths.get(filename)), "UTF-8");
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

String content = new String(Files.readAllBytes(Paths.get("readMe.txt")), StandardCharsets.UTF_8);
String data = IO.from(new File("data.txt")).toString();
 try
{
  String content = new Scanner(new File("file.txt")).useDelimiter("\\Z").next();
  System.out.println(content);
}
catch(FileNotFoundException e)
{
  System.out.println("not found!");
}
public String fromFileInJar(String path) {
    try ( Scanner scanner 
            = new Scanner(getClass().getResourceAsStream(path))) {
        return scanner.useDelimiter("\\A").next();
    }
}
my.jar/com/some/thing/a.txt
String myTxt = fromFileInJar("/com/com/thing/a.txt");
String sMessage = String.join("\n", reader.lines().collect(Collectors.toList()));
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()]));
}
public String readStringFromFile(String filePath) throws IOException {
    String fileContent = new String(Files.readAllBytes(Paths.get(filePath)));
    return fileContent;
}
String file = ...
Path path = Paths.get(file);
String content = Files.readString(path);
// Or readString(path, someCharset), if you need a Charset different from UTF-8
public String readFile() throws IOException {
        File fileToRead = new File("file path");
        List<String> fileLines = Files.readAllLines(fileToRead.toPath());
        return StringUtils.join(fileLines, StringUtils.EMPTY);
}