前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何使用Java逐行读取大文本文件?

如何使用Java逐行读取大文本文件?

作者头像
用户7886150
修改2020-12-11 10:36:10
2.6K0
修改2020-12-11 10:36:10
举报
文章被收录于专栏:bit哲学院

参考链接: Java中Scanner和BufferReader类之间的区别

我需要使用Java逐行读取大约5-6 GB的大型文本文件。  

 我如何快速做到这一点?  

#1楼 

 这是一个示例,该示例具有完整的错误处理并支持Java 7之前的字符集规范。使用Java 7,您可以使用try-with-resources语法,从而使代码更简洁。  

 如果只需要默认字符集,则可以跳过InputStream并使用FileReader。  

InputStream ins = null; // raw byte-stream

Reader r = null; // cooked reader

BufferedReader br = null; // buffered for readLine()

try {

    String s;

    ins = new FileInputStream("textfile.txt");

    r = new InputStreamReader(ins, "UTF-8"); // leave charset out for default

    br = new BufferedReader(r);

    while ((s = br.readLine()) != null) {

        System.out.println(s);

    }

}

catch (Exception e)

{

    System.err.println(e.getMessage()); // handle exception

}

finally {

    if (br != null) { try { br.close(); } catch(Throwable t) { /* ensure close happens */ } }

    if (r != null) { try { r.close(); } catch(Throwable t) { /* ensure close happens */ } }

    if (ins != null) { try { ins.close(); } catch(Throwable t) { /* ensure close happens */ } }

}

 这是Groovy版本,具有完整的错误处理:  

File f = new File("textfile.txt");

f.withReader("UTF-8") { br ->

    br.eachLine { line ->

        println line;

    }

}

#2楼 

 java-8发布后(2014年3月),您将可以使用流:  

try (Stream<String> lines = Files.lines(Paths.get(filename), Charset.defaultCharset())) {

  lines.forEachOrdered(line -> process(line));

}

 打印文件中的所有行:  

try (Stream<String> lines = Files.lines(file, Charset.defaultCharset())) {

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

}

#3楼 

 在Java 8中,您可以执行以下操作:  

try (Stream<String> lines = Files.lines (file, StandardCharsets.UTF_8))

{

    for (String line : (Iterable<String>) lines::iterator)

    {

        ;

    }

}

 一些注意事项: Files.lines返回的流(与大多数流不同)需要关闭。 由于这里提到的原因,我避免使用forEach() 。 奇怪的代码(Iterable<String>) lines::iterator将Stream转换为Iterable。  

#4楼 

 在Java 7中:  

String folderPath = "C:/folderOfMyFile";

Path path = Paths.get(folderPath, "myFileName.csv"); //or any text file eg.: txt, bat, etc

Charset charset = Charset.forName("UTF-8");

try (BufferedReader reader = Files.newBufferedReader(path , charset)) {

  while ((line = reader.readLine()) != null ) {

    //separate all csv fields into string array

    String[] lineVariables = line.split(","); 

  }

} catch (IOException e) {

    System.err.println(e);

}

#5楼 

 Java-9:  

try (Stream<String> stream = Files.lines(Paths.get(fileName))) {

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

}

#6楼 

 FileReader不允许您指定编码,如果需要指定编码,请改用InputStreamReader :  

try {

    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "Cp1252"));         

    String line;

    while ((line = br.readLine()) != null) {

        // process the line.

    }

    br.close();

} catch (IOException e) {

    e.printStackTrace();

}

 如果从Windows导入了此文件,则该文件可能具有ANSI编码(Cp1252),因此必须指定编码。  

#7楼 

 您还可以使用apache commons io :  

File file = new File("/home/user/file.txt");

try {

    List<String> lines = FileUtils.readLines(file);

} catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

}

#8楼 

 我通常会简单地执行阅读例程:  

void readResource(InputStream source) throws IOException {

    BufferedReader stream = null;

    try {

        stream = new BufferedReader(new InputStreamReader(source));

        while (true) {

            String line = stream.readLine();

            if(line == null) {

                break;

            }

            //process line

            System.out.println(line)

        }

    } finally {

        closeQuiet(stream);

    }

}

static void closeQuiet(Closeable closeable) {

    if (closeable != null) {

        try {

            closeable.close();

        } catch (IOException ignore) {

        }

    }

}

#9楼 

 在Java 8中,还有一种替代方法来使用Files.lines() 。 如果您的输入源不是文件,而是更抽象的东西(例如Reader或InputStream ,则可以通过BufferedReader的lines()方法对这些行进行流处理。  

 例如:  

try (BufferedReader reader = new BufferedReader(...)) {

  reader.lines().forEach(line -> processLine(line));

}

 将为BufferedReader读取的每个输入行调用processLine() 。  

#10楼 

 您可以使用扫描仪扫描整个文本,然后逐行浏览文本。 当然,您应该导入以下内容:  

import java.io.File;

import java.io.FileNotFoundException;

import java.util.Scanner;

public static void readText throws FileNotFoundException {

    Scanner scan = new Scanner(new File("samplefilename.txt"));

    while(scan.hasNextLine()){

        String line = scan.nextLine();

        //Here you can manipulate the string the way you want

    }

}

 扫描程序基本上会扫描所有文本。 while循环用于遍历整个文本。  

 .hasNextLine()函数是一个布尔值,如果文本中还有更多行,则返回true。 .nextLine()函数为您提供整行作为字符串,然后您可以使用所需的方式。 尝试使用System.out.println(line)打印文本。  

 注意:.txt是文件类型的文本。  

#11楼 

 实现这一目标的明确方法,  

 例如:  

 如果当前目录中有dataFile.txt  

import java.io.*;

import java.util.Scanner;

import java.io.FileNotFoundException;

public class readByLine

{

    public readByLine() throws FileNotFoundException

    {

        Scanner linReader = new Scanner(new File("dataFile.txt"));

        while (linReader.hasNext())

        {

            String line = linReader.nextLine();

            System.out.println(line);

        }

        linReader.close();

    }

    public static void main(String args[])  throws FileNotFoundException

    {

        new readByLine();

    }

}

 输出如下   

#12楼 

 使用Java 8 读取文件  

  package com.java.java8;

    import java.nio.file.Files;

    import java.nio.file.Paths;

    import java.util.stream.Stream;

    /**

     * The Class ReadLargeFile.

     *

     * @author Ankit Sood Apr 20, 2017

     */

    public class ReadLargeFile {

        /**

         * The main method.

         *

         * @param args

         *            the arguments

         */

        public static void main(String[] args) {

        try {

            Stream<String> stream = Files.lines(Paths.get("C:\\Users\\System\\Desktop\\demoData.txt"));

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

        } catch (Exception e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

        }

    }

#13楼 

BufferedReader br;

FileInputStream fin;

try {

    fin = new FileInputStream(fileName);

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

    /*Path pathToFile = Paths.get(fileName);

    br = Files.newBufferedReader(pathToFile,StandardCharsets.US_ASCII);*/

    String line = br.readLine();

    while (line != null) {

        String[] attributes = line.split(",");

        Movie movie = createMovie(attributes);

        movies.add(movie);

        line = br.readLine();

    }

    fin.close();

    br.close();

} catch (FileNotFoundException e) {

    System.out.println("Your Message");

} catch (IOException e) {

    System.out.println("Your Message");

}

 这个对我有用。 希望它也能帮助您。  

#14楼 

您可以使用流来更精确地做到这一点:  

Files.lines(Paths.get("input.txt")).forEach(s -> stringBuffer.append(s);

#15楼 

 您可以使用以下代码:  

import java.io.BufferedReader;

import java.io.File;

import java.io.FileReader;

import java.io.IOException;

public class ReadTextFile {

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

        try {

            File f = new File("src/com/data.txt");

            BufferedReader b = new BufferedReader(new FileReader(f));

            String readLine = "";

            System.out.println("Reading file using Buffered Reader");

            while ((readLine = b.readLine()) != null) {

                System.out.println(readLine);

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}

#16楼 

 我记录并测试了10种不同的方式来读取Java文件 ,然后通过使它们读取从1KB到1GB的测试文件来相互对抗。 这是读取1GB测试文件最快的3种文件读取方法。  

 请注意,在运行性能测试时,我没有向控制台输出任何内容,因为这确实会降低测试速度。 我只是想测试原始读取速度。  

 1)java.nio.file.Files.readAllBytes()  

 在Java 7、8、9中进行了测试。这总体上是最快的方法。 读取1GB文件始终不到1秒。  

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-1GB.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);

    }

  }

}

 2)java.nio.file.Files.lines()  

 这已在Java 8和9中成功测试,但由于缺少对lambda表达式的支持,因此在Java 7中无法使用。 读取1GB的文件大约需要3.5秒,与读取较大的文件相比,它排在第二位。  

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-1GB.txt";

    File file = new File(fileName);

    try (Stream linesStream = Files.lines(file.toPath())) {

      linesStream.forEach(line -> {

        System.out.println(line);

      });

    }

  }

}

 3)BufferedReader  

 经过测试,可以在Java 7、8、9中运行。读取1GB测试文件大约需要4.5秒。  

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-1GB.txt";

    FileReader fileReader = new FileReader(fileName);

    try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {

      String line;

      while((line = bufferedReader.readLine()) != null) {

        System.out.println(line);

      }

    }

  }

 您可以在此处找到所有10种文件读取方法的完整排名。  

#17楼 

 通过使用org.apache.commons.io软件包,可以提高性能,尤其是在使用Java 6及更低版本的旧代码中。  Java7具有更好的API,更少的异常处理和更有用的方法  

LineIterator lineIterator =null;

    try{

    lineIterator = FileUtils.lineIterator(new File("/home/username/m.log"), "windows-1256");//second parameter is optionanl

    while (lineIterator.hasNext()){

      String currentLine = lineIterator.next();   

     //some operation

    } 

    }finally {  

     LineIterator.closeQuietly(lineIterator);

    }

 专家  

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->

<dependency>

    <groupId>commons-io</groupId>

    <artifactId>commons-io</artifactId>

    <version>2.6</version>

</dependency>

#18楼 

 看这个博客:  

 Java逐行读取文件-Java教程 

  可以指定缓冲区大小,也可以使用默认大小。 对于大多数用途,默认值足够大。  

// Open the file

FileInputStream fstream = new FileInputStream("textfile.txt");

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

String strLine;

//Read File Line By Line

while ((strLine = br.readLine()) != null)   {

  // Print the content on the console

  System.out.println (strLine);

}

//Close the input stream

fstream.close();

#19楼 

 您需要在class BufferedReader使用readLine()方法。 从该类创建一个新对象,然后对他进行操作,然后将其保存到字符串中。  

 BufferReader Javadoc  

#20楼 

 您可以使用扫描仪类  

Scanner sc=new Scanner(file);

sc.nextLine();

#21楼 

 常见的模式是使用  

try (BufferedReader br = new BufferedReader(new FileReader(file))) {

    String line;

    while ((line = br.readLine()) != null) {

       // process the line.

    }

}

 如果您假设没有字符编码,则可以更快地读取数据。 例如ASCII-7,但差别不大。 您处理数据的时间很可能会花费更长的时间。  

 编辑:一种不太常用的模式,可以避免line泄漏的范围。  

try(BufferedReader br = new BufferedReader(new FileReader(file))) {

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

        // process the line.

    }

    // line is not visible here.

}

 更新:在Java 8中,您可以执行  

try (Stream<String> stream = Files.lines(Paths.get(fileName))) {

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

}

 注意:您必须将Stream放在try-with-resource块中,以确保在其上调用#close方法,否则,直到GC稍后将不再关闭基础文件句柄。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档