在Java中读取纯文本文件
在Java中,似乎有不同的方式来读取和写入文件数据在Java中读取纯文本文件,java,file-io,ascii,Java,File Io,Ascii,在Java中,似乎有不同的方式来读取和写入文件数据 我想从文件中读取ASCII数据。可能的方法和它们的区别是什么?ASCII是一个文本文件,您可以使用它进行阅读。Java还支持使用从二进制文件读取。如果正在读取的文件很大,那么您可能希望使用a上的a来提高读取性能 详细讲解如何使用读卡器 我还建议你下载并阅读这本精彩但免费的书 在Java 7中: 或 在Java 8中: 最简单的方法是在Java中使用Scanner类和FileReader对象。简单的例子: Scanner in = new Sc
我想从文件中读取ASCII数据。可能的方法和它们的区别是什么?ASCII是一个文本文件,您可以使用它进行阅读。Java还支持使用从二进制文件读取。如果正在读取的文件很大,那么您可能希望使用a上的a来提高读取性能 详细讲解如何使用读卡器 我还建议你下载并阅读这本精彩但免费的书 在Java 7中: 或 在Java 8中:
最简单的方法是在Java中使用Scanner类和FileReader对象。简单的例子:
Scanner in = new Scanner(new FileReader("filename.txt"));
扫描仪有几种读取字符串、数字等的方法。。。您可以在Java文档页面上查找有关这方面的更多信息
例如,将整个内容读入字符串:
此外,如果您需要特定编码,您可以使用此编码而不是FileReader:
我最喜欢的读取小文件的方法是使用BufferedReader和StringBuilder。它非常简单,切中要害,虽然不是特别有效,但对于大多数情况来说已经足够好了:
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
String everything = sb.toString();
} finally {
br.close();
}
有人指出,在Java 7之后,您应该使用自动关闭功能:
try(BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
String everything = sb.toString();
}
当我阅读这样的字符串时,我通常希望对每行进行一些字符串处理,所以我选择了这个实现
不过,如果我真的想把一个文件读入字符串,我总是将Apache与类IOUtils.toString方法一起使用。您可以在此处查看源代码:
使用Java 7更简单:
try(FileInputStream inputStream = new FileInputStream("foo.txt")) {
String everything = IOUtils.toString(inputStream);
// do something with everything string
}
其中的方法也可能非常方便,例如:
/**
* Reads the contents of a file line by line to a List
* of Strings using the default encoding for the VM.
*/
static List readLines(File file)
到目前为止,我还没有看到其他答案中提到这一点。但是如果Best意味着速度,那么新的javai/onio可能会提供最快的性能,但对学习者来说并不总是最容易理解的
你想对文本做什么?文件是否足够小,可以放入内存?我会尽量找到最简单的方法来处理您的需要的文件。FileUtils库非常适合处理此问题
for(String line: FileUtils.readLines("my-text-file"))
System.out.println(line);
我编写的这段代码对于非常大的文件要快得多:
public String readDoc(File f) {
String text = "";
int read, N = 1024 * 1024;
char[] buffer = new char[N];
try {
FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr);
while(true) {
read = br.read(buffer, 0, N);
text += new String(buffer, 0, read);
if(read < N) {
break;
}
}
} catch(Exception ex) {
ex.printStackTrace();
}
return text;
}
下面是不使用外部库的另一种方法:
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public String readFile(String filename)
{
String content = null;
File file = new File(filename); // For example, foo.txt
FileReader reader = null;
try {
reader = new FileReader(file);
char[] chars = new char[(int) file.length()];
reader.read(chars);
content = new String(chars);
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(reader != null){
reader.close();
}
}
return content;
}
可能没有缓冲I/O的速度快,但非常简洁:
String content;
try (Scanner scanner = new Scanner(textFile).useDelimiter("\\Z")) {
content = scanner.next();
}
\Z模式告诉扫描仪分隔符是EOF。以下是一个简单的解决方案:
String content;
content = new String(Files.readAllBytes(Paths.get("sample.txt")));
在Java中,从文件读取数据最简单的方法是使用file类读取文件,使用Scanner类读取文件内容
public static void main(String args[])throws Exception
{
File f = new File("input.txt");
takeInputIn2DArray(f);
}
public static void takeInputIn2DArray(File f) throws Exception
{
Scanner s = new Scanner(f);
int a[][] = new int[20][20];
for(int i=0; i<20; i++)
{
for(int j=0; j<20; j++)
{
a[i][j] = s.nextInt();
}
}
}
Scanner in = new Scanner(new File("filename.txt"));
while (in.hasNext()) { // Iterates each line in the file
String line = in.nextLine();
// Do something with line
}
in.close(); // Don't forget to close resource leaks
PS:别忘了导入java.util.*;对于基于JSF的Maven web应用程序,只需使用ClassLoader和Resources文件夹读取所需的任何文件即可: 将要读取的任何文件放入Resources文件夹中。 将Apache Commons IO依赖项放入POM中:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
您可以使用BufferedReader对文本文件、属性文件、架构等执行相同的操作。:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
BufferedReader br;
try {
br = new BufferedReader(new FileReader("/fileToRead.txt"));
try {
String x;
while ( (x = br.readLine()) != null ) {
// Printing out each line in the file
System.out.println(x);
}
}
catch (IOException e) {
e.printStackTrace();
}
}
catch (FileNotFoundException e) {
System.out.println(e);
e.printStackTrace();
}
这基本上与Jesus Ramos的答案完全相同,只是使用文件而不是FileReader,再加上迭代来逐步遍历文件的内容
public static void main(String args[])throws Exception
{
File f = new File("input.txt");
takeInputIn2DArray(f);
}
public static void takeInputIn2DArray(File f) throws Exception
{
Scanner s = new Scanner(f);
int a[][] = new int[20][20];
for(int i=0; i<20; i++)
{
for(int j=0; j<20; j++)
{
a[i][j] = s.nextInt();
}
}
}
Scanner in = new Scanner(new File("filename.txt"));
while (in.hasNext()) { // Iterates each line in the file
String line = in.nextLine();
// Do something with line
}
in.close(); // Don't forget to close resource leaks
。。。抛出FileNotFoundException如果这是为了简化结构,请使用:
import static kiss.API.*;
class App {
void run() {
String line;
try (Close in = inOpen("file.dat")) {
while ((line = readLine()) != null) {
println(line);
}
}
}
}
为此提供一个衬里:
import com.google.common.base.Charsets;
import com.google.common.io.Files;
String contents = Files.toString(filePath, Charsets.UTF_8);
我必须对不同的方法进行基准测试。我将对我的发现发表评论,但简而言之,最快的方法是在FileInputStream上使用普通的旧BufferedInputStream。如果必须读取多个文件,那么三个线程将把总执行时间减少到大约一半,但是添加更多线程将逐渐降低性能,直到使用二十个线程比仅使用一个线程完成所需时间长三倍 假设您必须读取文件并对其内容执行有意义的操作。在这里的示例中,从日志中读取行,并对包含超过某个阈值的值的行进行计数。因此,我假设一行Java 8 Files.linesPaths.get/path/to/file.txt.mapline->line.split;这不是一种选择 我在Java1.8、Windows7以及SSD和HDD驱动器上进行了测试 我编写了六种不同的实现: rawParse:在FileInputStream上使用BufferedInputStream,然后逐字节剪切读取的行。这比任何其他单线程方法都要好,但对于非ASCII文件来说可能非常不方便 lineReaderParse:在文件阅读器上使用BufferedReader,逐行读取,通过调用String.split拆分行。这大约比rawParse慢20% lineReaderParseParallel:这与lineReaderParse相同,但它使用多个线程。这是所有情况下最快的选择 nioFilesParse:使用java.nio.files.files.lines nioAsyncParse:使用带有完成处理程序和线程池的AsynchronousFileChannel nioMemoryMappedParse:使用内存映射文件。这确实是一个糟糕的主意,它会导致执行时间比任何其他impleme至少长三倍 自我陶醉 这是在四核i7和SSD驱动器上读取204个4MB文件的平均时间。文件是动态生成的,以避免磁盘缓存
rawParse 11.10 sec
lineReaderParse 13.86 sec
lineReaderParseParallel 6.00 sec
nioFilesParse 13.52 sec
nioAsyncParse 16.06 sec
nioMemoryMappedParse 37.68 sec
我发现在SSD上运行或使用硬盘驱动器作为SSD运行之间的差异比我预期的要小,大约快15%。这可能是因为文件是在未分段的HDD上生成的,并且它们是按顺序读取的,因此旋转驱动器几乎可以像SSD一样运行
我对nioAsyncParse实现的低性能感到惊讶。要么我以错误的方式实现了某些东西,要么使用NIO和完成处理程序的多线程实现与使用java.ioAPI的单线程实现的性能相同,甚至更差。此外,使用CompletionHandler的异步解析在代码行中要长得多,并且比在旧流上的直接实现更难正确实现
现在,这六个实现后面跟着一个包含它们的类,再加上一个可参数化的main方法,该方法允许处理文件数量、文件大小和并发度。请注意,文件大小的变化为正负20%。这是为了避免由于所有文件大小完全相同而产生任何影响
rawParse
线规
lineReaderParseParallel
niofilessparse
异步解析
所有案例的全面可运行实施
下面是用Java8方法实现的一行代码。假设text.txt文件位于Eclipse项目目录的根目录中
Files.lines(Paths.get("text.txt")).collect(Collectors.toList());
以下是三种工作和测试方法: 使用BufferedReader 使用扫描仪 使用文件阅读器 使用Scanner类读取整个文件,无需循环
这可能不是问题的确切答案。这只是另一种读取文件的方法,在这种方法中,您没有在Java代码中显式指定文件的路径,而是将其作为命令行参数读取 使用以下代码
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class InputReader{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s="";
while((s=br.readLine())!=null){
System.out.println(s);
}
}
}
只需继续并使用以下工具运行它:
java InputReader < input.txt
这将从input.txt读取并写入output.txt。为您提供一个声明性的一行代码:
new TextOf(new File("a.txt")).asString();
您可以使用readAllLines和join方法在一行中获取整个文件内容:
String str = String.join("\n",Files.readAllLines(Paths.get("e:\\text.txt")));
默认情况下,它使用UTF-8编码,正确读取ASCII数据
您还可以使用readAllBytes:
String str = new String(Files.readAllBytes(Paths.get("e:\\text.txt")), StandardCharsets.UTF_8);
我认为readAllBytes更快更精确,因为它不会将新行替换为\n,新行也可能是\r\n。这取决于您的需要,哪一种适合您。我记录并测试了它们在不同文件大小(从1KB到1GB)下的速度,以下是实现这一点的三种方法:
java.nio.file.Files.readAllBytes
经过测试,可以在Java7、8和9中工作
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);
}
}
}
java.io.BufferedReader.readLine
经过测试,可以在Java7、8、9中工作
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile_BufferedReader_ReadLine {
public static void main(String [] args) throws IOException {
String fileName = "c:\\temp\\sample-10KB.txt";
FileReader fileReader = new FileReader(fileName);
try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {
String line;
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
}
}
}
java.nio.file.Files.lines
这已在Java8和Java9中测试过,但由于lambda表达式要求,在Java7中不起作用
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.stream.Stream;
public class ReadFile_Files_Lines {
public static void main(String[] pArgs) throws IOException {
String fileName = "c:\\temp\\sample-10KB.txt";
File file = new File(fileName);
try (Stream linesStream = Files.lines(file.toPath())) {
linesStream.forEach(line -> {
System.out.println(line);
});
}
}
}
实际上,缓冲流类的性能要高得多,以至于NIO.2API包含专门返回这些流类的方法,部分原因是为了鼓励您在应用程序中始终使用缓冲流 以下是一个例子:
Path path = Paths.get("/myfolder/myfile.ext");
try (BufferedReader reader = Files.newBufferedReader(path)) {
// Read from the stream
String currentLine = null;
while ((currentLine = reader.readLine()) != null)
//do your code here
} catch (IOException e) {
// Handle file I/O exception...
}
您可以替换此代码
BufferedReader reader = Files.newBufferedReader(path);
与
我推荐这篇文章来学习JavaNIO和IO的主要用法
String fileName = 'yourFileFullNameWithPath';
File file = new File(fileName); // Creates a new file object for your file
FileReader fr = new FileReader(file);// Creates a Reader that you can use to read the contents of a file read your file
BufferedReader br = new BufferedReader(fr); //Reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.
上述一组行可以写入一行,如下所示:
BufferedReader br = new BufferedReader(new FileReader("file.txt")); // Optional
添加到字符串生成器如果文件很大,建议使用字符串生成器,否则使用普通字符串对象
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
String everything = sb.toString();
} finally {
br.close();
}
只需使用Java8流。最直观的方法是在Java11 Files.readString中引入的
try {
File f = new File("filename.txt");
Scanner r = new Scanner(f);
while (r.hasNextLine()) {
String data = r.nextLine();
JOptionPane.showMessageDialog(data);
}
r.close();
} catch (FileNotFoundException ex) {
JOptionPane.showMessageDialog("Error occurred");
ex.printStackTrace();
}
PHP已经有几十年了!☺ 我做了一个小的调整,如果到达最后一行,\n就停止添加换行符。在线时编码!=null{sb.appendline;line=br.readLine;//仅当curline不是最后一行时添加新行。..ifline!=null{sb.append\n;}类似于Apache Common IO IOUTILSTORLING的代码是sun.misc.IOUTILSTORLING,它包含在Sun/Oracle JRE中。为了提高性能,请始终优先调用sb.append'\n'而不是sb.append\n,因为向StringBuilder追加字符的速度比StringFileReader抛出FileNotFoundException和BufferedRead抛出IOException的速度快,因此您必须捕获它们。不需要直接使用读卡器,也不需要尤蒂尔斯。java7内置了读取整个文件/所有行的方法:请参阅,如果您使用简单的字符串连接而不是StringBuilder,则速度会更快,我怀疑这一点……我认为主要的速度增益来自于读取1MB 1024*1024块。不过,您也可以通过将1024*1024作为第二个参数传递给BufferedReader构造函数来实现这一点。以这种方式使用+=可以得到二次曲线!任务的复杂性应为线性com
复杂性。这将开始爬网超过几mb的文件。要解决这个问题,你要么将文本块保存在列表中,要么使用前面提到的stringbuilder。比什么快得多?它肯定不会比附加到StringBuffer更快-1@gb96我对缓冲区的大小也有同样的想法,但中的详细实验在类似的环境中给出了令人惊讶的结果:16KB的缓冲区一致且明显更快。选择读取器实际上取决于您需要文件内容做什么。如果文件很小,并且您需要所有文件,那么我们的基准测试会更快:1.8-2x,只需使用FileReader即可读取所有文件,或者至少读取足够大的块。如果您是逐行处理,那么就使用BufferedReader。使用文件时是否会保留行顺序。行…forEach。。。。我的理解是,在此操作之后,顺序将是任意的。Files.lines…forEach…不保留行的顺序,而是并行执行,@Dash。如果顺序很重要,您可以使用Files.lines….forEachOrdered…,它应该保留顺序,但没有验证。@Palec这很有趣,但您能否引用文档中的话,其中说明Files.lines….forEach。。。是并行执行的吗?我认为只有在使用Files.lines…parallel.forEach…显式地使流并行时,才会出现这种情况。我最初的公式不是防弹的,@KlitosKyriacou。关键是它不能保证任何顺序,原因是很容易并行化。如果要保留顺序,请使用。或者如果您更喜欢更现代、更积极维护的库,则它在其类中具有类似的实用程序。或者你只是简单地使用内置方法来获取所有行:apache commons上的链接似乎已经死了。我也不同意关闭,因为它没有建设性。幸运的是,这很可能是重复的。很好的答案,例如in,无循环:{{{Scanner sc=new Scannerfile,UTF-8;sc.useDelimiter$^;//regex匹配nothing String text=sc.next;sc.close;}}}}}}非常有趣的是,python中没有什么比read更有趣的了,要将整个文件读取到字符串,这是最简单的方法:或者使用try with resources tryFileReader reader=new filereader文件我注意到了file.length,这对utf-16文件的效果如何?此技术假设读取填充了缓冲区;字符数等于字节数;内存中的字节数;并且字节数适合一个整数-1@HermesTrismegistus我提供了四个错误的原因。StefanReich完全同意我的观点。它也内置于java7中:@PeterLawrey可能意味着。随着最广泛意义的转移,Google link可能会随着时间的推移而改变内容,但这与他的查询相匹配,看起来是正确的。不幸的是,现在没有readLinesString,readLinesFile被弃用,取而代之的是readLinesFile,Charset。编码也可以作为字符串提供。while in.hasNext{System.out.println in.next;}@Hissain但比bufferedReader更易于使用,必须用try将其包围起来Catch@JesusRamos不是,你为什么这么认为?这比while line=br.readLine!=null{sb.appendline;}?一个非常相关的,由Jesus Ramos编写。True,应该是:ifscanner.hasNext content=scanner.next;这对我在安卓4.4上失败了。仅读取1024个字节。文件与文件阅读器:对于文件阅读器,文件必须存在,并且操作系统权限必须允许访问。使用文件,可以测试这些权限或检查文件是否为目录。文件具有有用的功能:isFile、isDirectory、listFiles、canExecute、canRead、canWrite、exists、mkdir、delete。File.createTempFile写入系统默认临时目录。此方法将返回可用于打开FileOutputStream对象等的文件对象。如果项目中存在文件夹,如何给出路径?java.nio.file.Files呢?我们现在可以只使用readAllLines、readAllBytes和lines。@Nery Jr,优雅而简单最好最简单。你不能在“任何你想要的文件”上使用它。您只能将其用于已打包到JAR或WAR文件中的资源。您应该说明它是如何完成的,而不是提供后续链接
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class InputReader{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s="";
while((s=br.readLine())!=null){
System.out.println(s);
}
}
}
java InputReader < input.txt
java InputReader < input.txt > output.txt
new TextOf(new File("a.txt")).asString();
String str = String.join("\n",Files.readAllLines(Paths.get("e:\\text.txt")));
String str = new String(Files.readAllBytes(Paths.get("e:\\text.txt")), StandardCharsets.UTF_8);
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);
}
}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile_BufferedReader_ReadLine {
public static void main(String [] args) throws IOException {
String fileName = "c:\\temp\\sample-10KB.txt";
FileReader fileReader = new FileReader(fileName);
try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {
String line;
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
}
}
}
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.stream.Stream;
public class ReadFile_Files_Lines {
public static void main(String[] pArgs) throws IOException {
String fileName = "c:\\temp\\sample-10KB.txt";
File file = new File(fileName);
try (Stream linesStream = Files.lines(file.toPath())) {
linesStream.forEach(line -> {
System.out.println(line);
});
}
}
}
Path path = Paths.get("/myfolder/myfile.ext");
try (BufferedReader reader = Files.newBufferedReader(path)) {
// Read from the stream
String currentLine = null;
while ((currentLine = reader.readLine()) != null)
//do your code here
} catch (IOException e) {
// Handle file I/O exception...
}
BufferedReader reader = Files.newBufferedReader(path);
BufferedReader br = new BufferedReader(new FileReader("/myfolder/myfile.ext"));
String fileName = 'yourFileFullNameWithPath';
File file = new File(fileName); // Creates a new file object for your file
FileReader fr = new FileReader(file);// Creates a Reader that you can use to read the contents of a file read your file
BufferedReader br = new BufferedReader(fr); //Reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.
BufferedReader br = new BufferedReader(new FileReader("file.txt")); // Optional
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
String everything = sb.toString();
} finally {
br.close();
}
import java.util.stream.Stream;
import java.nio.file.*;
import java.io.*;
class ReadFile {
public static void main(String[] args) {
String filename = "Test.txt";
try(Stream<String> stream = Files.lines(Paths.get(filename))) {
stream.forEach(System.out:: println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
File f = new File("filename.txt");
Scanner r = new Scanner(f);
while (r.hasNextLine()) {
String data = r.nextLine();
JOptionPane.showMessageDialog(data);
}
r.close();
} catch (FileNotFoundException ex) {
JOptionPane.showMessageDialog("Error occurred");
ex.printStackTrace();
}
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String args[]) throws IOException {
String content = Files.readString(Paths.get("D:\\sandbox\\mvn\\my-app\\my-app.iml"));
System.out.print(content);
}
}