Get the contents of the last line of a Java file

Asked

Viewed 1,081 times

1

I need to recover a file always the last line written. I know one way to do this would be:

import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
public class LineReader {
    public static void main(String[] args) throws Exception {
        LineNumberReader lineCounter = new LineNumberReader(new InputStreamReader(new FileInputStream("C:\\MyFile.txt")));
        String nextLine = null;
        try {
            while ((nextLine = lineCounter.readLine()) != null) {
                if (nextLine == null)
                    break;
                System.out.println(nextLine);
            }
            System.out.println("Total number of line in this file " + lineCounter.getLineNumber());
        } catch (Exception done) {
            done.printStackTrace();
        }
    }
}

But is there any method ready in java to get this line without having to go through all the lines of the file? Even more than I’ll ever know how many lines he already has.

4 answers

4

Try to use the method Files.readAllLines(Path):

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;

/**
 * @author Victor Stafusa
 */
public class LerArquivo {

    public static void main(String[] args) throws IOException {
        List<String> linhas = Files.readAllLines(new File("C:\\MyFile.txt").toPath());
        System.out.println("Número de linhas: " + linhas.size());
        System.out.println("Última linha: " + linhas.get(linhas.size() - 1));
    }
}
  • And if the file is 20GB?

  • @Tommelo In this case you will probably have one OutOfMemoryError. If not, it should work, but it will clutter up the memory and make a lot of work for the garbage collector. However, if you are having to read 20 Gb text files sequentially, your approach to the problem is clearly not appropriate.

  • So in this case, if I have to read the last line of a 20GB file this approach of Files.readAllLines is not appropriate, correct?

  • @Tommelo: https://answall.com/a/244450/132

  • Exactly! It was my question, a solution that meets any scenario. I think it would be nice to edit and put the solution with Randomaccessfile.

2

  • Right, but how do I import this Apache Commons IO API?

  • 2

    Instead of Charset.forName("UTF-8"), use StandardCharsets.UTF_8. This avoids you having to capture the UnsupportedCharsetException that will never occur.

  • @Good Victorstafusa! I will edit.

  • 1

    @Lucaspletsch you can add this dependency to your pom.xml file: https://mvnrepository.com/artifact/commons-io/commons-io/2.5

  • @Tommelo, :I’ve never done this. I found this Maven pom.xml file. Just paste this dependency anywhere in the file? I took a blank space and taped it like this:

  • <!-- https://mvnrepository.com/artifact/commons-io/commons-io -> <dependency> <groupid>Commons-io</groupid> <artifactId>Commons-io</artifactId> <version>2.5</version> </dependency y y>

  • @Tommelo But now, in my class in Eclipse, where I am coding. How I know the correct library name to do the "import" ?

  • 1

    @Lucaspletsch import org.apache.Commons.io.input.Reversedlinesfilereader; You can use Ctrl + shift + o for the eclipse to import to you.

  • 1

    @Lucaspletsch http://www.mauda.com.br/? p=1308

  • @Tommelo Ok, I included the dependency there in pom.xml, saved, closed and opened Eclipse again, and made the import as you said. However, Eclipse goes on to say that "org.apache can not be resolved". From "Commons" on it does not mark it as wrong, only "org.apache".

  • 1

    @Lucaspletsch follows this last link I sent you first. Create the Maven project and then place the dependency in pom.xml.

  • @Tommelo Ok, I’ll try this. Thank you!!

Show 7 more comments

0

In Java version 7 the Files.readAllLines(Path p, Charset Cs) method requires the final attribute to specify the character that will serve as a reference for the line break. I suggest you add:

    List<String> lines = Files.readAllLines(
          new File("C:\\MyFile.txt").toPath(),     
          Charset.defaultCharset()
    );
  • But this form does not return the last line only. What author wants is to return only the last.

  • But it can: ultima = Lines[Lines.Count - 1]

0

For files that are very large (a few gigabytes), most approaches would be to read it sequentially, which would be too slow and could give a OutOfMemoryError if the program stored all this in memory.

To resolve this issue, follow an approach that reads the file backwards:

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * @author Victor Stafusa
 */
public class LerArquivoDeTrasParaFrente {
    public static void main(String[] args) throws IOException {
        File f = new File("C:\\MyFile.txt");
        try (RandomAccessFile raf = new RandomAccessFile(f, "r")) {
            byte b = 0;
            long t = raf.length();
            for (long n = 0; t - n >= 0 && b != '\r' && b != '\n'; n++) {
                raf.seek(t - n);
                b = (byte) raf.read();
            }
            System.out.println("A última linha é: " + raf.readLine());
        }
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.