Encontre o número de linhas em um arquivo usando Java

Encontre o número de linhas em um arquivo usando Java

1. Visão geral

Neste tutorial, aprenderemoshow to find the number of lines in a file using Java com a ajuda de APIs Java IO padrão,Google Guavae a bibliotecaApache Commons IO.

2. NIO2Files

Observe que, neste tutorial, usaremos os seguintes valores de amostra como o nome do arquivo de entrada e o número total de linhas:

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

Java 7 introduziu muitas melhorias nas bibliotecas IO existentes e as empacotou emNIO2:

Vamos começar comFiles e ver como podemos usar sua API para contar o número de linhas:

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

Ou simplesmente usando o métodoFiles#readAllLines:

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

3. NIOFileChannel

Agora vamos verificarFileChannel, uma alternativa Java NIO de alto desempenho para ler o número de linhas:

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

Embora oFileChannel tenha sido introduzido no JDK 4,the above solution works only with JDK 7 or higher.

4. Google GuavaFiles

Uma biblioteca alternativa de terceiros seria a classe Google GuavaFiles. Essa classe também pode ser usada para contar o número total de linhas de maneira semelhante ao que vimos comFiles#readAllLines.

Vamos começar adicionandothe guava dependency em nossopom.xml:


    com.google.guava
    guava
    28.0-jre

E então podemos usarreadLines para obterList das linhas do arquivo:

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

5. Apache Commons IOFileUtils

Agora, vamos verApache Commons IO APIFileUtils, uma solução paralela para Guava.

Para usar a biblioteca, temos que incluirthe commons-io dependency empom.xml:


    commons-io
    commons-io
    2.6

Nesse ponto, podemos usarFileUtils#lineIterator do Apache Commons IO, que limpa algumas das manipulações de arquivo para nós:

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

Como podemos ver, isso é um pouco mais detalhado que a solução do Google Guava.

6. BufferedReader

Então, e as formas da velha escola? Se não estivermos no JDK 7 e não pudermos usar uma biblioteca de terceiros, temosBufferedReader:

@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

Ou podemos usarLineNumberReader, uma subclasse direta deBufferedReader, que é um pouco menos prolixo:

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

Aqui estamoscalling the skip method para ir para o final do arquivo, ewe’re adding 1 to the total number of lines contados já que a numeração da linha começa em 0.

8. Scanner

E, finalmente, se já estivermos usandoScanner  como parte de uma solução maior, ele pode resolver o problema para nós também:

@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. Conclusão

Neste tutorial, exploramos maneiras diferentes de encontrar o número de linhas em um arquivo usando Java. Como o objetivo principal de todas essas APIs não é contar o número de linhas em um arquivo, é recomendável escolher a solução certa para nossa necessidade.

Como sempre, o código-fonte deste tutorial está disponívelover on GitHub.