1. 개요

이 예제에서는 표준 Java IO API, Google Guav aApache Commons IO 라이브러리를 사용하여 Java사용하여 파일에서 행 수를 찾는 방법을 배웁니다 .

2. NIO2 파일

이 사용방법(예제)에서는 입력 파일 이름과 총 줄 수로 다음 샘플 값을 사용합니다.

static final String INPUT_FILE_NAME = "src/main/resources/input.txt";
static final int NO_OF_LINES = 45;

Java 7은 기존 IO 라이브러리에 많은 개선 사항을 도입하고 NIO2 아래에 패키지화했습니다 .

파일 부터 시작하여 해당 API를 사용하여 줄 수를 계산하는 방법을 살펴 보겠습니다 .

@Test
public void whenUsingNIOFiles_thenReturnTotalNumberOfLines() throws IOException {
    try (Stream<String> fileStream = Files.lines(Paths.get(INPUT_FILE_NAME))) {
        int noOfLines = (int) fileStream.count();
        assertEquals(NO_OF_LINES, noOfLines);
    }
}

또는 단순히 Files # readAllLines 메서드 를 사용하여 :

@Test
public void whenUsingNIOFilesReadAllLines_thenReturnTotalNumberOfLines() throws IOException {
    List<String> fileStream = Files.readAllLines(Paths.get(INPUT_FILE_NAME));
    int noOfLines = fileStream.size();
    assertEquals(NO_OF_LINES, noOfLines);
}

3. NIO 되는 FileChannel

이제 행 수를 읽는 고성능 Java NIO 대안 인 FileChannel을 살펴 보겠습니다 .

@Test
public void whenUsingNIOFileChannel_thenReturnTotalNumberOfLines() throws IOException {
    int noOfLines = 1;
    try (FileChannel channel = FileChannel.open(Paths.get(INPUT_FILE_NAME), StandardOpenOption.READ)) {
        ByteBuffer byteBuffer = channel.map(MapMode.READ_ONLY, 0, channel.size());
        while (byteBuffer.hasRemaining()) {
            byte currentByte = byteBuffer.get();
            if (currentByte == '\n')
                noOfLines++;
       }
    }
    assertEquals(NO_OF_LINES, noOfLines);
}

FileChannel 이 JDK 4에 도입 되었지만 위의 솔루션은 JDK 7 이상에서만 작동합니다 .

4. 구글 구아바 파일

대체 타사 라이브러리는 Google Guava Files 클래스입니다. 이 클래스는 Files # readAllLines에서 본 것과 유사한 방식으로 총 줄 수를 계산하는 데 사용할 수도 있습니다  .

의 추가하여 시작하자 구아바 의존성 우리의 pom.xml 파일을 :

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>28.0-jre</version>
</dependency>

그런 다음 readLines 사용 하여 파일 행 List 을 가져올 수 있습니다  .

@Test
public void whenUsingGoogleGuava_thenReturnTotalNumberOfLines() throws IOException {
    List<String> lineItems = Files.readLines(Paths.get(INPUT_FILE_NAME)
      .toFile(), Charset.defaultCharset());
    int noOfLines = lineItems.size();
    assertEquals(NO_OF_LINES, noOfLines);
}

5. Apache Commons IO FileUtils

이제 Guava의 병렬 솔루션 인 Apache Commons IO FileUtils API를 살펴 보겠습니다  .

라이브러리를 사용하려면 pom.xmlcommons-io 의존성 을 포함해야합니다 .

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.8.0</version>
</dependency>

이 시점에서 Apache Commons IO의 FileUtils # lineIterator 를 사용하여 파일 처리 중 일부를 정리할 수 있습니다  .

@Test
public void whenUsingApacheCommonsIO_thenReturnTotalNumberOfLines() throws IOException {
    int noOfLines = 0;
    LineIterator lineIterator = FileUtils.lineIterator(new File(INPUT_FILE_NAME));
    while (lineIterator.hasNext()) {
        lineIterator.nextLine();
        noOfLines++;
    }
    assertEquals(NO_OF_LINES, noOfLines);
}

보시다시피 이것은 Google Guava 솔루션보다 약간 더 장황합니다.

6. BufferedReader

그렇다면 구식 방식은 어떻습니까? JDK 7이 아니고 타사 라이브러리를 사용할 수 없다면 BufferedReader 가 있습니다 .

@Test
public void whenUsingBufferedReader_thenReturnTotalNumberOfLines() throws IOException {
    int noOfLines = 0;
    try (BufferedReader reader = new BufferedReader(new FileReader(INPUT_FILE_NAME))) {
        while (reader.readLine() != null) {
            noOfLines++;
        }
    }
    assertEquals(NO_OF_LINES, noOfLines);
}

7. LineNumberReader

또는 BufferedReader 의 직접 하위 클래스 인 LineNumberReader 를 사용할 수 있습니다 .

@Test
public void whenUsingLineNumberReader_thenReturnTotalNumberOfLines() throws IOException {
    try (LineNumberReader reader = new LineNumberReader(new FileReader(INPUT_FILE_NAME))) {
        reader.skip(Integer.MAX_VALUE);
        int noOfLines = reader.getLineNumber() + 1;
        assertEquals(NO_OF_LINES, noOfLines);
    }
}

여기서 파일의 끝으로 가기 위해 skip 메소드호출하고 , 행 번호 매기기가 0에서 시작하기 때문에 계산 된 총 행 수에 1을 더합니다 .

8. 스캐너

마지막으로 더 큰 솔루션의 일부로 스캐너 이미 사용하고 있다면 문제도 해결할 수 있습니다.

@Test
public void whenUsingScanner_thenReturnTotalNumberOfLines() throws IOException {
    try (Scanner scanner = new Scanner(new FileReader(INPUT_FILE_NAME))) {
        int noOfLines = 0;
        while (scanner.hasNextLine()) {
            scanner.nextLine();
            noOfLines++;
        }
        assertEquals(NO_OF_LINES, noOfLines);
    }
}

9. 결론

이 사용방법(예제)에서는 Java를 사용하여 파일에서 줄 수를 찾는 다양한 방법을 탐색했습니다. 이러한 모든 API의 주요 목적은 파일의 줄 수를 계산하는 것이 아니기 때문에 필요에 맞는 올바른 솔루션을 선택하는 것이 좋습니다.

항상 그렇듯이이 사용방법(예제)의 소스 코드는 GitHub에서 사용할 수 있습니다 .