source

Java를 사용하여 큰 텍스트 파일을 한 줄씩 읽는 방법은 무엇입니까?

factcode 2022. 11. 16. 21:25
반응형

Java를 사용하여 큰 텍스트 파일을 한 줄씩 읽는 방법은 무엇입니까?

자바에서 5~6GB 정도의 큰 텍스트 파일을 한 줄씩 읽어야 합니다.

어떻게 하면 빨리 할 수 있을까요?

일반적인 패턴은

try (BufferedReader br = new BufferedReader(new FileReader(file))) {
    String line;
    while ((line = br.readLine()) != null) {
       // process the line.
    }
}

ASCII-7과 같이 문자 인코딩이 없다고 가정하면 데이터를 더 빨리 읽을 수 있지만 큰 차이는 없습니다.데이터를 사용하여 수행하는 작업은 훨씬 더 오래 걸릴 수 있습니다.

EDIT:으로, 「 」 「 」 「 」 「 」 「 」 「 」 「 」의 합니다.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);
}

메모: 스트림에서 #close 메서드를 호출하려면 스트림의 Try-with-Resource 블록을 설정해야 합니다.그렇지 않으면 기본 파일 핸들은 GC에서 한참 후에 닫힐 때까지 닫히지 않습니다.

다음 블로그를 보세요.

버퍼 크기를 지정하거나 기본 크기를 사용할 수 있습니다.기본값은 대부분의 경우 충분히 큽니다.

// 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();

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);
}

다음은 Java 7 이전 버전의 완전한 오류 처리 및 지원되는 charset 사양의 샘플입니다.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;
    }
}

자바에서 파일을 읽는 10가지 방법을 문서화하고 테스트한 후 1KB에서 1GB까지 테스트 파일로 읽게 하여 서로 비교했습니다.다음은 1GB 테스트 파일을 읽는 가장 빠른 세 가지 파일 읽기 방법입니다.

퍼포먼스 테스트를 실행할 때 콘솔에 아무것도 출력하지 않았습니다.그렇게 하면 테스트가 매우 느려지기 때문입니다.그냥 읽기 속도를 테스트해 보고 싶었어요.

1) java.nio.파일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.파일Files.lines()

이것은 Java 8과 9에서 성공적으로 테스트되었지만 람다 식을 지원하지 않기 때문에 Java 7에서는 작동하지 않습니다.1GB 파일을 읽는 데 3.5초 정도 걸렸는데, 큰 파일을 읽는 것보다 2위를 차지했습니다.

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) Buffered Reader

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가지 파일 읽기 방법에 대한 전체 순위는 여기에서 확인할 수 있습니다.

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반복할 수 있는 사람에게 스트림을 던집니다.

스캐너를 사용하여 텍스트 전체를 스캔하고 텍스트를 한 줄씩 훑어볼 수 있습니다.물론 다음 항목을 Import해야 합니다.

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)텍스트를 인쇄합니다.

Side Note: .txt는 파일 형식의 텍스트입니다.

할 수 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 에서 Import 했을 경우는, ANSI 부호화(Cp1252)가 설정되어 있을 가능성이 있기 때문에, 부호화를 지정할 필요가 있습니다.

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);
}

Java 8에서는 를 사용하는 대신 사용할 수도 있습니다.입력 소스가 파일이 아닌 보다 추상적인 파일인 경우Reader ★★★InputStream, 를 통해 회선을 스트리밍할 수 있습니다.BufferedReaders lines()★★★★★★ 。

예를 들어 다음과 같습니다.

try (BufferedReader reader = new BufferedReader(...)) {
  reader.lines().forEach(line -> processLine(line));
}

를 호출합니다.processLine(), 「」로 수 있습니다.BufferedReader.

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();
        }
    }
}

스캐너 클래스를 사용할 수 있습니다.

Scanner sc=new Scanner(file);
sc.nextLine();

Java 9:

try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
    stream.forEach(System.out::println);
}

하다를 요.readLine() in the method in the method in 。class BufferedReader. 새 이 해당 클래스에서 새 개체를 만들고 이 메서드를 사용하여 문자열에 저장합니다.

BufferReader Javadoc

이 목표를 달성하기 위한 확실한 방법은

예를 들어 다음과 같습니다.

「 」가 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();
    }
}

출력은 다음과 같습니다.

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");
}

저는 좋아요.당신에게도 도움이 되길 바랍니다.

스트림을 사용하여 보다 정확하게 수행할 수 있습니다.

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

저는 보통 읽기 루틴을 직설적으로 합니다.

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) {
        }
    }
}

org.apache.commons.io 패키지를 사용함으로써 특히 Java 6 이하를 사용하는 레거시 코드에서 더 높은 성능을 얻을 수 있었습니다.

Java 7은 예외 처리를 줄이고 보다 유용한 메서드를 사용하여 보다 나은 API를 제공합니다.

LineIterator lineIterator = null;
try {
    lineIterator = FileUtils.lineIterator(new File("/home/username/m.log"), "windows-1256"); // The second parameter is optionnal
    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>

다음 코드를 사용할 수 있습니다.

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();
        }

    }

}

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();
}

다음과 같이 파일 데이터를 한 줄씩 읽을 수 있습니다.

String fileLoc = "fileLocationInTheDisk";

List<String> lines = Files.lines(Path.of(fileLoc), StandardCharsets.UTF_8).collect(Collectors.toList());

언급URL : https://stackoverflow.com/questions/5868369/how-can-i-read-a-large-text-file-line-by-line-using-java

반응형