怎么设这java字符,如何从文件内容创建Java字符串?

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

我一直在使用下面的成语一段时间了。 它似乎是最广泛的,至少在我访问过的网站上。

是否有更好/不同的方式将文件读入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();

}

}

30个解决方案

1305 votes

读取文件中的所有文本

这是Java 7的一个紧凑,健壮的习惯用法,包含在一个实用程序方法中:

static String readFile(String path, Charset encoding)

throws IOException

{

byte[] encoded = Files.readAllBytes(Paths.get(path));

return new String(encoded, encoding);

}

从文件中读取文本行

Java 7添加了一种方便的方法来将文件读取为文本行,表示为Charset.这种方法是“有损”的,因为行分隔符从每行的末尾被剥离。

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

在Java 8中,Charset添加了一个新方法Charset以生成readLine().如果在读取文件时遇到BufferedReader,则它被包装在Charset中,因为close()不接受抛出已检查异常的lambda。

try (BufferedReader r = Files.newBufferedReader(path, encoding)) {

r.lines().forEach(System.out::println);

}

还有一个Charset方法做了非常相似的事情,直接返回readLine()。 但我不喜欢它。 BufferedReader需要拨打close(); 这在API上记录不足,我怀疑很多人甚至没有注意到Stream有一个close()方法。 所以你的代码看起来非常相似,如下所示:

try (Stream lines = Files.lines(path, encoding)) {

lines.forEach(System.out::println);

}

不同的是你有一个Charset分配给一个变量,我尝试避免这种做法,以便我不小心尝试两次调用流。

内存利用率

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

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

对于读取大文件,您需要为程序设计不同的设计,一个从流中读取一块文本,处理它,然后继续下一个,重复使用相同的固定大小的内存块。 这里,“大”取决于计算机规格。 如今,这个阈值可能是几千兆字节的RAM。 如果您的输入“记录”恰好是单独的行,则使用Charset的第三种方法是执行此操作的一种方法。 (使用readLine()的方法BufferedReader是这种方法的程序等效。)

字符编码

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

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

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

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

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

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

erickson answered 2018-11-28T12:07:23Z

306 votes

Commons IOException:

IOException

使用默认编码将文件内容读入String   对于VM。 该文件始终关闭。

参数:

IOException - 要读取的文件,不能为null

返回:   文件内容,永远不会为空

抛出:    - IOException - 如果发生I / O错误

以来:   Commons IO 1.3.1

该类(间接)使用的代码是:

Apache License 2.0下的IOUtils.java。

public static long copyLarge(InputStream input, OutputStream output)

throws IOException {

byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];

long count = 0;

int n = 0;

while (-1 != (n = input.read(buffer))) {

output.write(buffer, 0, n);

count += n;

}

return count;

}

它与Ritche_W使用的非常相似。

Willi aus Rohr answered 2018-11-28T12:08:27Z

165 votes

从这个页面非常精简的解决方案:

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

如果要设置charset

Pablo Grisafi answered 2018-11-28T12:08:51Z

72 votes

如果您正在寻找不涉及第三方库(例如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();

}

}

Dónal answered 2018-11-28T12:09:11Z

66 votes

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

import com.google.common.base.Charsets;

import com.google.common.io.Files;

// ...

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

由Oscar Reyes编辑

这是引用库中的(简化)底层代码:

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类。

OscarRyz answered 2018-11-28T12:09:44Z

58 votes

String content = new String(Files.readAllBytes(Paths.get("readMe.txt")), "UTF-8");

从java 7开始,你就可以这样做。

Jobin Joseph answered 2018-11-28T12:10:04Z

51 votes

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 "";

}

user590444 answered 2018-11-28T12:10:24Z

46 votes

该代码将规范化换行符,这可能是你真正想做的事情,也可能不是。

这是一个替代方案,它没有这样做,并且(IMO)比NIO代码更容易理解(虽然它仍然使用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();

}

}

Jon Skeet answered 2018-11-28T12:10:48Z

45 votes

如果您需要字符串处理(并行处理),Java 8具有出色的Stream API。

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示例sample/lambda/BulkDataOperations中提供了更多示例,可以从Oracle Java SE 8下载页面下载

另一个班轮示例

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

Andrei N answered 2018-11-28T12:11:17Z

23 votes

如果是文本文件,为什么不使用apache commons-io?

它有以下方法

public static String readFileToString(File file) throws IOException

如果您希望使用行作为列表

public static List readLines(File file) throws IOException

Home in Time answered 2018-11-28T12:11:46Z

16 votes

收集了从磁盘或网络读取文件为字符串的所有可能方法。

番石榴:谷歌使用类public static String getDiskFile_Lines( File file ) throws IOException {

StringBuffer text = new StringBuffer();

FileInputStream fileStream = new FileInputStream( file );

BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );

for ( String line; (line = br.readLine()) != null; )

text.append( line + System.lineSeparator() );

return text.toString();

},public static String getDiskFile_Lines( File file ) throws IOException {

StringBuffer text = new StringBuffer();

FileInputStream fileStream = new FileInputStream( file );

BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );

for ( String line; (line = br.readLine()) != null; )

text.append( line + System.lineSeparator() );

return text.toString();

}

public static String getDiskFile_Lines( File file ) throws IOException {

StringBuffer text = new StringBuffer();

FileInputStream fileStream = new FileInputStream( file );

BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );

for ( String line; (line = br.readLine()) != null; )

text.append( line + System.lineSeparator() );

return text.toString();

}

APACHE - 使用类IOUtils,FileUtils的COMMONS IO

public static String getDiskFile_Lines( File file ) throws IOException {

StringBuffer text = new StringBuffer();

FileInputStream fileStream = new FileInputStream( file );

BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );

for ( String line; (line = br.readLine()) != null; )

text.append( line + System.lineSeparator() );

return text.toString();

}

使用Stream API的Java 8 BufferReader

public static String getDiskFile_Lines( File file ) throws IOException {

StringBuffer text = new StringBuffer();

FileInputStream fileStream = new FileInputStream( file );

BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );

for ( String line; (line = br.readLine()) != null; )

text.append( line + System.lineSeparator() );

return text.toString();

}

扫描仪类与正则表达式public static String getDiskFile_Lines( File file ) throws IOException {

StringBuffer text = new StringBuffer();

FileInputStream fileStream = new FileInputStream( file );

BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );

for ( String line; (line = br.readLine()) != null; )

text.append( line + System.lineSeparator() );

return text.toString();

}.匹配输入的开头。

public static String getDiskFile_Lines( File file ) throws IOException {

StringBuffer text = new StringBuffer();

FileInputStream fileStream = new FileInputStream( file );

BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );

for ( String line; (line = br.readLine()) != null; )

text.append( line + System.lineSeparator() );

return text.toString();

}

Java 7(public static String getDiskFile_Lines( File file ) throws IOException {

StringBuffer text = new StringBuffer();

FileInputStream fileStream = new FileInputStream( file );

BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );

for ( String line; (line = br.readLine()) != null; )

text.append( line + System.lineSeparator() );

return text.toString();

})

public static String getDiskFile_Lines( File file ) throws IOException {

StringBuffer text = new StringBuffer();

FileInputStream fileStream = new FileInputStream( file );

BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );

for ( String line; (line = br.readLine()) != null; )

text.append( line + System.lineSeparator() );

return text.toString();

}

public static String getDiskFile_Lines( File file ) throws IOException {

StringBuffer text = new StringBuffer();

FileInputStream fileStream = new FileInputStream( file );

BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );

for ( String line; (line = br.readLine()) != null; )

text.append( line + System.lineSeparator() );

return text.toString();

}使用InputStreamReader。

public static String getDiskFile_Lines( File file ) throws IOException {

StringBuffer text = new StringBuffer();

FileInputStream fileStream = new FileInputStream( file );

BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );

for ( String line; (line = br.readLine()) != null; )

text.append( line + System.lineSeparator() );

return text.toString();

}

使用main方法访问上述方法的示例。

public static void main(String[] args) throws IOException {

String fileName = "E:/parametarisation.csv";

File file = new File( fileName );

String fileStream = commons_FileUtils( file );

// guava_DiskFile( file );

// streamFile_Buffer( file );

// getDiskFile_Java7( file );

// getDiskFile_Lines( file );

System.out.println( " File Over Disk : \n"+ fileStream );

try {

String src = "https://code.jquery.com/jquery-3.2.1.js";

URL url = new URL( src );

String urlStream = commons_IOUtils( url );

// guava_ServerFile( url );

// streamURL_Scanner( url );

// streamURL_Buffer( url );

System.out.println( " File Over Network : \n"+ urlStream );

} catch (MalformedURLException e) {

e.printStackTrace();

}

}

@看到

将InputStream转换为String的方法

Yash answered 2018-11-28T12:12:49Z

15 votes

将文件读取为二进制文件并在结尾处进行转换

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

}

}

Peter Lawrey answered 2018-11-28T12:13:09Z

15 votes

使用Java 7,这是我读取UTF-8文件的首选选项:

String content = new String(Files.readAllBytes(Paths.get(filename)), "UTF-8");

从Java 7开始,JDK具有新的java.nio.file API,它提供了许多快捷方式,因此简单文件操作并不总是需要第三方库。

Moritz Petersen answered 2018-11-28T12:13:33Z

15 votes

从JDK 11开始:

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

leventov answered 2018-11-28T12:13:53Z

14 votes

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

使用外部库。

将此代码复制到您的所有项目中。

创建自己的迷你库,其中包含您经常使用的功能。

你最好的选择可能是第二个,因为它的依赖性最小。

Claudiu answered 2018-11-28T12:14:31Z

7 votes

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

for(String line = reader.readLine(); line != null; line = reader.readLine()) {

stringBuilder.append(line);

stringBuilder.append(ls);

}

Dan Dyer answered 2018-11-28T12:14:52Z

6 votes

使用JDK 8或更高版本:

没有使用外部库

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

public String readStringFromFile(String filePath) throws IOException {

String fileContent = new String(Files.readAllBytes(Paths.get(filePath)));

return fileContent;

}

Saikat answered 2018-11-28T12:15:20Z

5 votes

如果您无权访问Files类,则可以使用本机解决方案。

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

}

Ilya Gazman answered 2018-11-28T12:15:40Z

4 votes

使用Apache commons-io中的IOUtils与StringWriter结合使用的灵活解决方案:

Reader input = new FileReader();

StringWriter output = new StringWriter();

try {

IOUtils.copy(input, output);

} finally {

input.close();

}

String fileContents = output.toString();

它适用于任何阅读器或输入流(不仅仅是文件),例如从URL读取时。

wau answered 2018-11-28T12:16:05Z

4 votes

public static String slurp (final File file)

throws IOException {

StringBuilder result = new StringBuilder();

BufferedReader reader = new BufferedReader(new FileReader(file));

try {

char[] buf = new char[1024];

int r = 0;

while ((r = reader.read(buf)) != -1) {

result.append(buf, 0, r);

}

}

finally {

reader.close();

}

return result.toString();

}

Scott S. McCoy answered 2018-11-28T12:16:20Z

3 votes

请注意,在使用fileInputStream.available()时,返回的整数不必表示实际文件大小,而是系统应该能够在不阻塞IO的情况下从流中读取的猜测字节数。 一种安全而简单的方式可能看起来像这样

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

}

应该认为这种方法不适合像UTF-8这样的多字节字符编码。

Henry answered 2018-11-28T12:16:45Z

3 votes

这个使用方法RandomAccessFile.readFully,它似乎可以从JDK 1.0获得!

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

}

}

}

barjak answered 2018-11-28T12:17:05Z

3 votes

您可以尝试Scanner和File类,几行解决方案

try

{

String content = new Scanner(new File("file.txt")).useDelimiter("\\Z").next();

System.out.println(content);

}

catch(FileNotFoundException e)

{

System.out.println("not found!");

}

jamesjara answered 2018-11-28T12:17:25Z

2 votes

在Scanner之后按Ctrl + F',我认为也应该列出Scanner解决方案。 以最容易阅读的方式,它是这样的:

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-resources来使代码更易于阅读。 没有更多关闭垃圾的东西。 但这主要是一种风格选择。

我发布这个主要是为了完成主义,因为如果你需要做很多事情,java.nio.file.Files中应该有更好的工作。

我的建议是使用Files#readAllBytes(Path)来获取所有字节,并将其提供给新的String(byte [] Charset)以获得一个你可以信任的String。 Charsets在你的一生中对你意味着什么,所以现在要小心这些东西。

其他人给了代码和东西,我不想偷走他们的荣耀。;)

Haakon Løtveit answered 2018-11-28T12:18:03Z

2 votes

使用这个库,它是一行:

String data = IO.from(new File("data.txt")).toString();

satnam answered 2018-11-28T12:18:23Z

2 votes

此外,如果您的文件恰好在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");

OscarRyz answered 2018-11-28T12:18:52Z

2 votes

在一行(Java 8)中,假设您有一个Reader:

String sMessage = String.join("\n", reader.lines().collect(Collectors.toList()));

Malcolm Boekhoff answered 2018-11-28T12:19:12Z

2 votes

基于@ erickson的回答,您可以使用:

public String readAll(String fileName) throws IOException {

List lines = Files.readAllLines(new File(fileName).toPath());

return String.join("\n", lines.toArray(new String[lines.size()]));

}

Muskovets answered 2018-11-28T12:19:32Z

2 votes

用户java.nio.Files读取所有文件行。

public String readFile() throws IOException {

File fileToRead = new File("file path");

List fileLines = Files.readAllLines(fileToRead.toPath());

return StringUtils.join(fileLines, StringUtils.EMPTY);

}

Nitin Vavdiya answered 2018-11-28T12:19:52Z

1 votes

我还不能评论其他条目,所以我会把它留在这里。

这里最好的答案之一([https://stackoverflow.com/a/326448/1521167]:]

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

}

}

还有一个缺陷。 它总是将新行char放在字符串的末尾,这可能会导致一些奇怪的错误。 我的建议是将其改为:

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

}

}

Ajk answered 2018-11-28T12:20:22Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值