Java是否有一行读取文本文件,就像C#一样?
我的意思是,在Java中是否存在与此类似的东西?:
String data = System.IO.File.ReadAllText("path to file");
如果不是......这样做的"最佳方式"是什么?
编辑:
我更喜欢Java标准库中的一种方式...我不能使用第三方库..
可能重复如何从文件内容创建Java字符串?
apache commons-io有:
String str = FileUtils.readFileToString(file,"utf-8");
但是标准java类中没有这样的实用程序。如果您(出于某种原因)不想要外部库,则必须重新实现它。以下是一些示例,您也可以看到它是如何通过commons-io或Guava实现的。
我使用FileUtils.readFileToString(file,encoding)版本 - 不妨推荐好习惯!
@Nick - 感谢您的建议
不在主Java库中,但您可以使用Guava:
String data = Files.asCharSource(new File("path.txt"), Charsets.UTF_8).read();
或读取行:
List lines = Files.readLines( new File("path.txt"), Charsets.UTF_8 );
当然,我确信还有其他第三方库可以让它同样容易 - 我只是最熟悉番石榴。
Java 7使用Files类改进了这种令人遗憾的事态(不要与Guava的同名类混淆),你可以从文件中获取所有行 - 没有外部库 - 使用:
List fileLines = Files.readAllLines(path, StandardCharsets.UTF_8);
或者成一个字符串:
String contents = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
// or equivalently:
StandardCharsets.UTF_8.decode(ByteBuffer.wrap(Files.readAllBytes(path)));
如果你需要一个干净的JDK开箱即用的东西,那么效果很好。那就是说,为什么你在没有番石榴的情况下编写Java?
第二个示例中的路径是Path类型,可以使用var path = Paths.get(filePathAsString)从String中检索;
所有Files方法都使用Path;看到java.nio.file包。 Paths.get()只是获取Path实例的一种方法。
Java 11通过Files.readString添加了对此用例的支持,示例代码:
Files.readString(Path.of("/your/directory/path/file.txt"));
在Java 11之前,标准库的典型方法是这样的:
public static String readStream(InputStream is) {
StringBuilder sb = new StringBuilder(512);
try {
Reader r = new InputStreamReader(is,"UTF-8");
int c = 0;
while ((c = r.read()) != -1) {
sb.append((char) c);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return sb.toString();
}
笔记:
要从文件中读取文本,请使用FileInputStream
如果性能很重要并且您正在读取大文件,则建议将流包装在BufferedInputStream中
流应该由调用者关闭
缓冲读卡器有一条读取线,比一次读取一个字符更好
如果您使用BufferedInputStream,它将没有什么区别
这样它就会在字符串中添加last(-1)。
不,它没有。它在条件下检查(c!= -1)
这真的不酷。返回字符串总是以-1结尾,因为while循环时不小心编码。
好抓,更新。
这是一个过时的答案。另请参阅下面的null指针的JDK / 11答案。
在Java 8(没有外部库)中,您可以使用流。此代码读取文件并将所有以","分隔的行放入String中。
try (Stream lines = Files.lines(myPath)) {
list = lines.collect(Collectors.joining(","));
} catch (IOException e) {
LOGGER.error("Failed to load file.", e);
}
使用JDK / 11,您可以使用Files.readString(Path path)将Path的完整文件作为字符串读取:
try {
String fileContent = Files.readString(Path.of("/foo/bar/gus"));
} catch (IOException e) {
// handle exception in i/o
}
JDK的方法文档内容如下:
/**
* Reads all content from a file into a string, decoding from bytes to characters
* using the {@link StandardCharsets#UTF_8 UTF-8} {@link Charset charset}.
* The method ensures that the file is closed when all content have been read
* or an I/O error, or other runtime exception, is thrown.
*
*
This method is equivalent to:
* {@code readString(path, StandardCharsets.UTF_8) }
*
* @param path the path to the file
*
* @return a String containing the content read from the file
*
* @throws IOException
* if an I/O error occurs reading from the file or a malformed or
* unmappable byte sequence is read
* @throws OutOfMemoryError
* if the file is extremely large, for example larger than {@code 2GB}
* @throws SecurityException
* In the case of the default provider, and a security manager is
* installed, the {@link SecurityManager#checkRead(String) checkRead}
* method is invoked to check read access to the file.
*
* @since 11
*/
public static String readString(Path path) throws IOException
这是关于你可以做到这一点的时间。我没有看到读取行并抛弃行结束编码的重点。
无需外部库。在转换为字符串之前,将缓冲文件的内容。
Path path = FileSystems.getDefault().getPath(directory, filename);
String fileContent = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
注意String(byte[], String)抛出UnsupportedEncodingException。您应该更喜欢String(byte[], Charset)构造函数以及StandardCharsets或Guava的Charsets中的常量。
这是一个仅代码的答案,你的答案没有提到它需要在将所有字节转换为字符串之前缓冲所有字节(即它的内存效率不是很高)。
如果使用由nullpointer发布的JDK 11,则不是一个单一的内容并且可能已过时。如果您有非文件输入流,仍然有用
InputStream inStream = context.getAssets().open(filename);
Scanner s = new Scanner(inStream).useDelimiter("\\A");
String string = s.hasNext() ? s.next() :"";
inStream.close();
return string;
以下是在一行中读取文本文件的3种方法,无需循环。我记录了15种从Java文件中读取的方法,这些方法来自那篇文章。
请注意,您仍然必须遍历返回的列表,即使实际调用读取文件的内容只需要1行,而不进行循环。
1)java.nio.file.Files.readAllLines() - 默认编码
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
public class ReadFile_Files_ReadAllLines {
public static void main(String [] pArgs) throws IOException {
String fileName ="c:\\temp\\sample-10KB.txt";
File file = new File(fileName);
List fileLinesList = Files.readAllLines(file.toPath());
for(String line : fileLinesList) {
System.out.println(line);
}
}
}
2)java.nio.file.Files.readAllLines() - 显式编码
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
public class ReadFile_Files_ReadAllLines_Encoding {
public static void main(String [] pArgs) throws IOException {
String fileName ="c:\\temp\\sample-10KB.txt";
File file = new File(fileName);
//use UTF-8 encoding
List fileLinesList = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
for(String line : fileLinesList) {
System.out.println(line);
}
}
}
3)java.nio.file.Files.readAllBytes()
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
public class ReadFile_Files_ReadAllBytes {
public static void main(String [] pArgs) throws IOException {
String fileName ="c:\\temp\\sample-10KB.txt";
File file = new File(fileName);
byte [] fileBytes = Files.readAllBytes(file.toPath());
char singleChar;
for(byte b : fileBytes) {
singleChar = (char) b;
System.out.print(singleChar);
}
}
}
无需外部库。在转换为字符串之前,将缓冲文件的内容。
String fileContent="";
try {
File f = new File("path2file");
byte[] bf = new byte[(int)f.length()];
new FileInputStream(f).read(bf);
fileContent = new String(bf,"UTF-8");
} catch (FileNotFoundException e) {
// handle file not found exception
} catch (IOException e) {
// handle IO-exception
}
但前提是您从未遵循I / O流教程并且不了解如何处理错误,以及是否要在将所有字符转换为字符串之前将其复制到缓冲区中。请描述您的答案,代码只有答案通常不会被投票。