是否有更好/不同的方法可以将文件读入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();
}
}
#1 楼
读取文件中的所有文本Java 11添加了readString()方法以将小文件读取为
String
,并保留行终止符: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);
}
从文件中读取文本行
Java 7添加了一种便捷方法,将文件读取为文本行,表示为
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模块。如果您使用的不是文件源,则可以在
lines()
中使用BufferedReader
方法。内存利用率
第一种方法,用于保留换行符,可能会临时需要几倍于文件大小的内存,因为在短时间内,原始文件内容(字节数组)和已解码字符(即使编码为8位,每个字符均为16位)在文件中)立即驻留在内存中。将安全文件应用于相对于可用内存较小的文件是最安全的。
第二种方法,读取行通常会提高内存效率,因为用于解码的输入字节缓冲区不需要包含整个文件。但是,它仍然不适用于相对于可用内存而言非常大的文件。
为了读取大文件,您需要为程序提供不同的设计,即从流中读取文本块,对其进行处理,然后再移至下一个,重新使用相同的固定大小的内存块。在此,“大”取决于计算机规格。如今,此阈值可能是许多GB的RAM。如果输入的“记录”恰好是单独的行,则使用
Stream<String>
的第三种方法是执行此操作的一种方法。 (使用readLine()
的BufferedReader
方法等效于此方法。)字符编码
原始文章中的示例缺少的一件事是字符编码。在某些特殊情况下,平台默认值是您所需要的,但是很少见,因此您应该能够证明自己的选择。
StandardCharsets
类为所有Java运行时所需的编码定义了一些常量:String content = readFile("test.txt", StandardCharsets.UTF_8);
Charset
类本身提供了平台默认值:String content = readFile("test.txt", Charset.defaultCharset());
注意:此答案在很大程度上取代了我的Java 6版本。 Java 7的实用程序安全地简化了代码,并且使用映射字节缓冲区的旧答案阻止了读取的文件被删除,直到对映射缓冲区进行垃圾回收为止。您可以通过此答案上的“已编辑”链接查看旧版本。
评论
从技术上讲,它在时间和空间上为O(n)。定性地讲,由于Strings的不可变性要求,因此很难记忆;暂时在内存中有两个char数据副本,外加用于编码字节的空间。假设某些单字节编码,(临时)文件中的每个字符将需要5个字节的内存。由于该问题专门要求一个String,这就是我所显示的,但是如果您可以使用由“ decode”返回的CharBuffer,则对内存的需求将大大减少。从时间上看,我认为您不会在核心Java库中更快地找到任何东西。
– erickson
09年6月17日在20:16
可能有错字? NIO有一个名为java.nio.charset.Charset的Charset(不是CharSet)类。这是CharSet应该是的吗?
–乔纳森·赖特(Jonathan Wright)
09年12月20日在22:43
注意:在执行了一些代码之后,我发现使用此方法读取文件后不能立即可靠地删除文件,在某些情况下这可能不是问题,但不是我的。可能与此问题有关:bugs.sun.com/bugdatabase/view_bug.do?bug_id=4715154吗?我终于接受了Jon Skeet的建议,该建议不受此bug的影响。无论如何,我只是想将信息提供给其他人,以防万一...
–SébastienNussbaumer
2010年8月19日15:47
@SébastienNussbaumer:我也碰到了这个问题。令人惊讶的是,该错误已被标记为“将无法修复”。本质上,这意味着FileChannel#map通常是不可用的。
–乔纳斯·普拉卡(Joonas Pulakka)
2010年11月9日,7:45
#2 楼
如果您愿意使用外部库,请查看Apache Commons IO(200KB JAR)。它包含一个org.apache.commons.io.FileUtils.readFileToString()
方法,允许您使用一行代码将整个File
读入String
。示例:
import java.io.*;
import java.nio.charset.*;
import org.apache.commons.io.*;
public String readFile() throws IOException {
File file = new File("data.txt");
return FileUtils.readFileToString(file, StandardCharsets.UTF_8);
}
评论
在您提供的网址中找不到该方法。
– OscarRyz
08年11月28日在18:52
在org.apache.commons.io.FileUtils类中
–西里尔·卡(Cyrille Ka)
08年11月28日在19:04
我也使用FileUtils,但我想知道使用FileUtils还是公认的nio答案之间有什么更好的选择?
–纪尧姆
2010-2-9在16:31
@Guillaume:最大的问题是您是否对依赖第三方库感到满意。如果您的项目中确实有Commons IO或Guava,则使用它们(只是为了简化代码;否则可能不会有明显的区别)。
– Jonik
2013年12月29日13:04
#3 楼
一个基于Scanner
的非常精简的解决方案:Scanner scanner = new Scanner( new File("poem.txt") );
String text = scanner.useDelimiter("\A").next();
scanner.close(); // Put this call in a finally block
或者,如果要设置字符集,请执行以下操作: />或者,使用try-with-resources块,它将为您调用
scanner.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
构造函数可以抛出IOException
。而且不要忘记导入java.io
和java.util
。来源:Pat Niemeyer的博客
评论
\\ A之所以有效,是因为没有“文件的其他开头”,因此您实际上已读取了最后一个令牌……这也是第一个。从未尝试使用\\ Z。还要注意,您可以读取任何可读的内容,例如文件,InputStreams,通道...当我不确定是否要读取一个文件或另一个文件时,有时我会使用此代码从Eclipse的显示窗口中进行读取。是的,classpath使我感到困惑。
– Pablo Grisafi
2011年9月16日20:16在
作为张贴者,我可以说我真的不知道该文件是否以及何时正确关闭...我从未在生产代码中编写此文件,仅将其用于测试或调试。
– Pablo Grisafi
2012年6月4日17:26
我认为它不能超过1024个字符
–异想天开
2012年7月4日14:32
扫描器实现Closeable(它在源代码上调用close)-因此,尽管优雅,但它实际上并不是单线的。缓冲区的默认大小为1024,但是Scanner会根据需要增加大小(请参见Scanner#makeSpace())
–earcam
2012年11月23日在9:43
对于带有java.util.NoSuchElementException的空文件,此操作将失败。
–SpaceTrucker
13年8月2日在9:16
#4 楼
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);
从Java 7开始,您就可以用这种方式。
评论
这应该作为答案接受-单行,没有外部库。
–樱桃
18年5月4日在16:07
即使文件中不存在换行符,它也会在末尾添加一个换行符
– Stefan Haberl
2月12日14:38
#5 楼
如果您正在寻找不涉及第三方库的替代方案(例如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();
}
}
评论
我认为这是最好的方法。查看java.sun.com/docs/books/tutorial/essential/io/scanning.html
–塔斯基
08年11月28日在19:19
接受String的Scanner构造函数不会将字符串视为要读取的文件名,而是将其视为要扫描的文本。我一直犯那个错误。 :-/
–艾伦·摩尔
08年11月29日在9:10
@Alan,很好。我对Don的答案进行了略微修改,以解决该问题(我希望如此)。
– Jonik
2010-4-17的10:12
fileContents.append(scanner.nextLine())。append(lineSeparator);
– ban-geoengineering
13年5月24日在10:53
将初始化语句更改为Scanner Scanner = new Scanner((Readable)new BufferedReader(new FileReader(file)));。否则,您只能捕获文件的一部分。
–杨伟
13-10-22在17:40
#6 楼
评论
这段代码已从long转换为int,这可能会弹出一些大文件的疯狂行为。有多余的空间吗?您在哪里关闭输入流?
– Mohamed Taher Alrefaie
13年4月22日在15:42
@ M-T-A:流已关闭,请注意在CharSource中使用Closer。答案中的代码不是实际的当前Guava来源。
– Jonik
13年12月29日在13:19
#7 楼
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 "";
}
评论
或更简单:new String(Files.readAllBytes(FileSystems.getDefault()。getPath(filename)));
–user321068
2012年8月6日在21:54
或新的String(Files.readAllBytes(Paths.get(filename))); :-)
– assafmo
13-4-6在12:09
发挥得很好,并且为了避免下一个谷歌搜索,Paths和FileSystems显然是1.7+。 (该死的!)
–松饼
13-4-9在19:51
可惜这个答案没有更多的票。我一直在寻找将文本文件转换为String的最快,最简单的方法。就是这样,如果我不上下滚动,我会错过的。 OP应考虑接受此答案以将其移至顶部。
–刺
13年4月16日在4:40
@Thorn这个答案有可怕的错误处理。不要在生产代码中使用此方法,或者更好:永远不要。
– xehpuk
2015年2月20日在23:35
#8 楼
如果需要字符串处理(并行处理),则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")));
评论
.parallel()是在您阅读这些行之后还是之前发生的?
–伊斯特万
2015年4月17日在20:17
由于调用了终端操作collect(...),因此开始了实际工作。流是一行一行地懒散地填充的。在处理(例如过滤和映射)之前无需读取存储器中的整个文件。
– Andrei N
2015年4月21日在15:17
在选择非空行之前进行修剪?
–索比昂·拉文·安德森(ThorbjørnRavn Andersen)
16年1月13日在19:16
#9 楼
该代码将使换行符规范化,这可能不是您真正想做的。这是一个不执行此操作的替代方法,它比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();
}
}
评论
请原谅我恢复了这么老的评论,但是您的意思是传递一个名为“ file”的String对象,还是应该改为一个File对象?
–布莱恩·拉森(Bryan Larson)
2013年6月5日19:17
好答案。 +1。但是这个答案已经12岁了。 Java现在具有try-with-resources。
– Harshal Parekh
11月10日20:32
#10 楼
收集了从磁盘或网络中以字符串形式读取文件的所有可能方法。Guava:Google使用类
Resources
,Files
static Charset charset = com.google.common.base.Charsets.UTF_8;
public static String guava_ServerFile( URL url ) throws IOException {
return Resources.toString( url, charset );
}
public static String guava_DiskFile( File file ) throws IOException {
return Files.toString( file, charset );
}
APACHE-使用类的命令IO IOUtils,FileUtils
static Charset encoding = org.apache.commons.io.Charsets.UTF_8;
public static String commons_IOUtils( URL url ) throws IOException {
java.io.InputStream in = url.openStream();
try {
return IOUtils.toString( in, encoding );
} finally {
IOUtils.closeQuietly(in);
}
}
public static String commons_FileUtils( File file ) throws IOException {
return FileUtils.readFileToString( file, encoding );
/*List<String> lines = FileUtils.readLines( fileName, encoding );
return lines.stream().collect( Collectors.joining("\n") );*/
}
使用Stream API的Java 8 BufferReader
public static String streamURL_Buffer( URL url ) throws IOException {
java.io.InputStream source = url.openStream();
BufferedReader reader = new BufferedReader( new InputStreamReader( source ) );
//List<String> lines = reader.lines().collect( Collectors.toList() );
return reader.lines().collect( Collectors.joining( System.lineSeparator() ) );
}
public static String streamFile_Buffer( File file ) throws IOException {
BufferedReader reader = new BufferedReader( new FileReader( file ) );
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
}
带有正则表达式
\A
的扫描仪类。 static String charsetName = java.nio.charset.StandardCharsets.UTF_8.toString();
public static String streamURL_Scanner( URL url ) throws IOException {
java.io.InputStream source = url.openStream();
Scanner scanner = new Scanner(source, charsetName).useDelimiter("\A");
return scanner.hasNext() ? scanner.next() : "";
}
public static String streamFile_Scanner( File file ) throws IOException {
Scanner scanner = new Scanner(file, charsetName).useDelimiter("\A");
return scanner.hasNext() ? scanner.next() : "";
}
Java 7(
java.nio.file.Files.readAllBytes
) public static String getDiskFile_Java7( File file ) throws IOException {
byte[] readAllBytes = java.nio.file.Files.readAllBytes(Paths.get( file.getAbsolutePath() ));
return new String( readAllBytes );
}
BufferedReader
使用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();
}
}
@see
将InputStream转换为字符串的方式
#11 楼
如果是文本文件,为什么不使用apache commons-io?它具有以下方法
public static String readFileToString(File file) throws IOException
如果要将行作为列表使用
public static List<String> readLines(File file) throws IOException
#12 楼
自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
评论
为什么,为什么要引入依赖于2018年默认字符集的新方法?
– mryan
18-09-24在7:49
@mryan此方法不依赖默认系统字符集。默认为UTF-8,可以。
– Leventov
18-09-24在11:39
@leventov你是对的! File.readAllLines也是如此!这使得文件API与旧方法不太一致,但这是更好的方法:)
– mryan
18-09-25在13:34
#13 楼
将文件读取为二进制文件并在末尾进行转换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();
}
}
#14 楼
Java尝试在所有方面都变得极为通用和灵活。结果,在脚本语言中相对简单的事情(您的代码将被python中的“open(file).read()
”代替)要复杂得多。除了使用外部库(例如提到的Willi aus Rohr)外,似乎没有什么更短的方法了。您的选择:使用外部库。
将此代码复制到所有项目中。
创建自己的迷你库,其中包含经常使用的功能。
您的最佳选择可能是第二名,因为它的依赖性最小。
评论
是的它使“高级”语言具有不同的含义。 Java与C相比具有较高的水平,但与Python或Ruby相比却具有较低的水平
– OscarRyz
08年11月28日在19:36
同意Java在高级抽象方面很长,但在便利方法上却很短
–Dónal
2011年5月11日在16:44
的确,Java处理文件的方法非常疯狂,其中许多似乎很复杂。但是,这与高级语言中的代码非常接近:byte [] bytes = Files.readAllBytes(someFile.toPath());
–刺
13年4月16日在20:45
#15 楼
对于Java 7,这是读取UTF-8文件的首选方法:String content = new String(Files.readAllBytes(Paths.get(filename)), "UTF-8");
由于Java 7,JDK具有新的
java.nio.file
API,该API提供了许多快捷方式,因此简单的文件操作并不总是需要第三方库。#16 楼
使用JDK 8或更高版本:不使用外部库
您可以从文件内容创建新的String对象(使用
java.nio.file
包中的类):public String readStringFromFile(String filePath) throws IOException {
String fileContent = new String(Files.readAllBytes(Paths.get(filePath)));
return fileContent;
}
评论
重复的莫里兹·彼得森(Moritz Petersen)的答案是谁写的:字符串内容=新字符串(Files.readAllBytes(Paths.get(filename)),“ UTF-8”);
–让·克里斯托弗·布兰查德(Jean-Christophe Blanchard)
18年11月29日在10:30
#17 楼
在同一主题上有一个变体,它使用for循环而不是while循环来限制line变量的范围。是否“更好”取决于个人喜好。for(String line = reader.readLine(); line != null; line = reader.readLine()) {
stringBuilder.append(line);
stringBuilder.append(ls);
}
评论
这会将换行符更改为默认的换行符选择。这可能是理想的,也可能是意料之外的。
– Peter Lawrey
2010-4-18的7:23
将编辑回滚到此答案,因为要缩小行变量的范围。编辑两次声明它,这将是编译错误。
–丹·代尔
13年8月1日在20:16
#18 楼
如果您无权访问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);
}
评论
示例字符集调用?
– Thufir
18/12/30在8:48
#19 楼
将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阅读。
#20 楼
请注意,在使用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之类的多字节字符编码。 >
评论
此代码可能会产生不可预测的结果。根据available()方法的文档,如果该方法返回0,则不能保证到达文件结尾。在这种情况下,您可能会得到不完整的文件。更糟糕的是,实际读取的字节数可能小于available()返回的值,在这种情况下,您的输出将损坏。
– wau
13年3月15日在13:32
#21 楼
这是一种使用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
}
}
}
#22 楼
您可以尝试使用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!");
}
#23 楼
根据@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()]));
}
#24 楼
用户java.nio.Files
读取文件的所有行。public String readFile() throws IOException {
File fileToRead = new File("file path");
List<String> fileLines = Files.readAllLines(fileToRead.toPath());
return StringUtils.join(fileLines, StringUtils.EMPTY);
}
#25 楼
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();
}
评论
我认为使用平台默认编码会带来不便。无论如何+1 :)
– OscarRyz
2010-2-9 15:53
在我看来,finally块不知道try块中定义的变量。 javac 1.6.0_21引发错误,找不到符号。
–天花板
2012年6月25日的16:11
您甚至尝试过自己的代码吗?您已经在try / catch块中定义了阅读器,因此在finally块中将无法访问它。
– mauron85
18-10-31在9:48
#26 楼
我还不能评论其他条目,所以我就把它留在这里。最好的答案之一在这里(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();
}
}
仍然有一个缺陷。它总是将换行符放在字符串的末尾,这可能会导致一些奇怪的错误。我的建议是将其更改为:
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();
}
}
评论
在第一种情况下,您可能会在末尾添加额外的换行符。在第二种情况下,您可能会省略一个。因此,两者都是错误的。看这篇文章
–帕特里克·帕克(Patrick Parker)
18-3-28在13:46
#27 楼
在扫描仪之后按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-resources进行代码更易于阅读。不再有点滴杂物乱扔一切。但这主要是一种风格选择方法。
我主要出于完成主义的目的发布此方法,因为如果您需要做很多事情,那么java.nio.file.Files中应该有一些东西我的建议是使用Files#readAllBytes(Path)来获取所有字节,并将其提供给新的String(byte [] Charset)以从中获得一个字符串,这是更好的工作。你可以信任。字符集在您的一生中对您而言将是卑鄙的,因此请当心这些内容。
其他人提供了代码和内容,我不想窃取他们的荣耀。 ;)
#28 楼
使用此库,只需一行:String data = IO.from(new File("data.txt")).toString();
评论
如果不计算库中的行。
–阿里
17年8月1日在2:13
#29 楼
另外,如果文件恰好位于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");
#30 楼
在一行(Java 8)中,假设您拥有阅读器:String sMessage = String.join("\n", reader.lines().collect(Collectors.toList()));
评论
谁能以一种非常简单的方式向我解释NIO是什么?每次我读到它,我都会迷失在频道的第n个提及中:(请记住,不能保证文件中的行分隔符不必与系统的行分隔符相同。
您能否最后插入一个合适的尝试关闭读者?有人可能会实际使用此示例,并在其代码中引入一个错误。
上面的代码有一个在最后一行添加额外的新行char的错误。它应该类似于以下if(line = reader.readLine())!= null){stringBuilder.append(line); } while(line = reader.readLine()!! = null){stringBuilder.append(ls); stringBuilder.append(line); }
Java 7引入了byte [] Files.readAllBytes(file);对于那些建议“单线”扫描仪解决方案的用户:不需要关闭它吗?