在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

在Java中,似乎有不同的方式来读取和写入文件数据


我想从文件中读取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);
    }
}