Anzahl der Zeilen in einer Datei in Java

213

Ich verwende große Datendateien. Manchmal muss ich nur die Anzahl der Zeilen in diesen Dateien kennen. Normalerweise öffne ich sie und lese sie Zeile für Zeile, bis ich das Ende der Datei erreicht habe

Ich habe mich gefragt, ob es einen intelligenteren Weg gibt, das zu tun

Kennzeichen
quelle

Antworten:

237

Dies ist die schnellste Version, die ich bisher gefunden habe, ungefähr sechsmal schneller als readLines. Bei einer 150-MB-Protokolldatei dauert dies 0,35 Sekunden, bei Verwendung von readLines () 2,40 Sekunden. Nur zum Spaß dauert der Befehl wc -l von Linux 0,15 Sekunden.

public static int countLinesOld(String filename) throws IOException {
    InputStream is = new BufferedInputStream(new FileInputStream(filename));
    try {
        byte[] c = new byte[1024];
        int count = 0;
        int readChars = 0;
        boolean empty = true;
        while ((readChars = is.read(c)) != -1) {
            empty = false;
            for (int i = 0; i < readChars; ++i) {
                if (c[i] == '\n') {
                    ++count;
                }
            }
        }
        return (count == 0 && !empty) ? 1 : count;
    } finally {
        is.close();
    }
}

EDIT, 9 1/2 Jahre später: Ich habe praktisch keine Java-Erfahrung, aber trotzdem habe ich versucht, diesen Code mit der folgenden LineNumberReaderLösung zu vergleichen, da es mich störte, dass niemand es tat. Es scheint, dass meine Lösung besonders für große Dateien schneller ist. Obwohl es ein paar Läufe zu dauern scheint, bis der Optimierer einen anständigen Job macht. Ich habe ein bisschen mit dem Code gespielt und eine neue Version erstellt, die durchweg am schnellsten ist:

public static int countLinesNew(String filename) throws IOException {
    InputStream is = new BufferedInputStream(new FileInputStream(filename));
    try {
        byte[] c = new byte[1024];

        int readChars = is.read(c);
        if (readChars == -1) {
            // bail out if nothing to read
            return 0;
        }

        // make it easy for the optimizer to tune this loop
        int count = 0;
        while (readChars == 1024) {
            for (int i=0; i<1024;) {
                if (c[i++] == '\n') {
                    ++count;
                }
            }
            readChars = is.read(c);
        }

        // count remaining characters
        while (readChars != -1) {
            System.out.println(readChars);
            for (int i=0; i<readChars; ++i) {
                if (c[i] == '\n') {
                    ++count;
                }
            }
            readChars = is.read(c);
        }

        return count == 0 ? 1 : count;
    } finally {
        is.close();
    }
}

Benchmark-Ergebnisse für eine 1,3-GB-Textdatei, y-Achse in Sekunden. Ich habe 100 Läufe mit derselben Datei durchgeführt und jeden Lauf mit gemessen System.nanoTime(). Sie können sehen, dass countLinesOldes einige Ausreißer gibt und countLinesNewkeine, und obwohl es nur ein bisschen schneller ist, ist der Unterschied statistisch signifikant. LineNumberReaderist deutlich langsamer.

Benchmark-Plot

Martinus
quelle
5
BufferedInputStream sollte die Pufferung für Sie durchführen, daher sehe ich nicht, wie die Verwendung eines Zwischenbyte [] -Arrays es schneller macht. Es ist unwahrscheinlich, dass Sie es viel besser machen, als readLine () wiederholt zu verwenden (da dies durch die API optimiert wird).
WDS
54
Sie werden diesen InputStream schließen, wenn Sie damit fertig sind, nicht wahr?
Bendin
5
Wenn das Puffern helfen würde, würde BufferedInputStream standardmäßig 8 KB puffern. Wenn Sie Ihr Byte [] auf diese Größe oder größer erhöhen, können Sie den BufferedInputStream löschen. Versuchen Sie es beispielsweise mit 1024 * 1024 Bytes.
Peter Lawrey
8
Zwei Dinge: (1) Die Definition eines Zeilenabschlusses in einer Java-Quelle ist ein Wagenrücklauf, ein Zeilenvorschub oder ein Wagenrücklauf, gefolgt von einem Zeilenvorschub. Ihre Lösung funktioniert nicht für CR, das als Leitungsterminator verwendet wird. Zugegeben, das einzige Betriebssystem, von dem ich glauben kann, dass es CR als Standardzeilenterminator verwendet, ist Mac OS vor Mac OS X. (2) Ihre Lösung setzt eine Zeichenkodierung wie US-ASCII oder UTF-8 voraus. Die Zeilenanzahl kann für Codierungen wie UTF-16 ungenau sein.
Nathan Ryan
2
Toller Code ... für eine 400-MB-Textdatei dauerte es nur eine Sekunde. Vielen Dank @martinus
user3181500
199

Ich habe eine andere Lösung für das Problem implementiert und fand es effizienter beim Zählen von Zeilen:

try
(
   FileReader       input = new FileReader("input.txt");
   LineNumberReader count = new LineNumberReader(input);
)
{
   while (count.skip(Long.MAX_VALUE) > 0)
   {
      // Loop just in case the file is > Long.MAX_VALUE or skip() decides to not read the entire file
   }

   result = count.getLineNumber() + 1;                                    // +1 because line index starts at 0
}
er.vikas
quelle
LineNumberReaderDas lineNumberFeld ist eine Ganzzahl ... Wird es nicht nur für Dateien umbrochen, die länger als Integer.MAX_VALUE sind? Warum hier lange vorbeischauen?
Epb
1
Das Hinzufügen von eins zur Zählung ist tatsächlich falsch. wc -lzählt die Anzahl der Zeilenumbrüche in der Datei. Dies funktioniert, da jede Zeile mit einer neuen Zeile abgeschlossen wird, einschließlich der letzten Zeile in einer Datei. Jede Zeile hat ein Zeilenumbruchzeichen, einschließlich der Leerzeilen, daher ist die Anzahl der Zeilenumbrüche Zeichen == Anzahl der Zeilen in einer Datei. Jetzt repräsentiert die lineNumberVariable in FileNumberReaderauch die Anzahl der gesehenen Zeilenumbrüche. Es beginnt bei Null, bevor eine neue Zeile gefunden wurde, und wird mit jedem gesehenen Zeilenumbruch erhöht. Fügen Sie also bitte keine zur Zeilennummer hinzu.
Alexander Torstling
1
@PB_MLT: Obwohl Sie Recht haben, dass eine Datei mit einer einzelnen Zeile ohne Zeilenumbruch als 0 Zeilen gemeldet wird, wird auf diese Weise wc -lauch diese Art von Datei gemeldet . Siehe auch stackoverflow.com/questions/729692/…
Alexander Torstling
@PB_MLT: Sie erhalten das gegenteilige Problem, wenn die Datei nur aus einer neuen Zeile besteht. Ihr vorgeschlagenes Algo würde 0 und wc -l1 zurückgeben. Ich kam zu dem Schluss, dass alle Methoden Fehler aufweisen, und implementierte eine basierend auf meinem Verhalten. Siehe meine andere Antwort hier.
Alexander Torstling
3
Ich habe diese Antwort
abgelehnt
30

Die akzeptierte Antwort hat einen Fehler von um eins für Dateien mit mehreren Zeilen, die nicht mit Zeilenumbruch enden. Eine einzeilige Datei, die ohne Zeilenumbruch endet, würde 1 zurückgeben, eine zweizeilige Datei, die ohne Zeilenumbruch endet, würde ebenfalls 1 zurückgeben. Hier ist eine Implementierung der akzeptierten Lösung, die dies behebt. Die EndsWithoutNewLine-Überprüfungen sind für alles außer dem endgültigen Lesen verschwenderisch, sollten jedoch im Vergleich zur Gesamtfunktion zeitlich trivial sein.

public int count(String filename) throws IOException {
    InputStream is = new BufferedInputStream(new FileInputStream(filename));
    try {
        byte[] c = new byte[1024];
        int count = 0;
        int readChars = 0;
        boolean endsWithoutNewLine = false;
        while ((readChars = is.read(c)) != -1) {
            for (int i = 0; i < readChars; ++i) {
                if (c[i] == '\n')
                    ++count;
            }
            endsWithoutNewLine = (c[readChars - 1] != '\n');
        }
        if(endsWithoutNewLine) {
            ++count;
        } 
        return count;
    } finally {
        is.close();
    }
}
DMulligan
quelle
6
Guter Fang. Ich bin mir nicht sicher, warum Sie die akzeptierte Antwort nicht einfach bearbeitet und in einem Kommentar notiert haben. Die meisten Leute werden nicht so weit lesen.
Ryan
@ Ryan, es fühlte sich einfach nicht richtig an, eine 4 Jahre alte akzeptierte Antwort mit mehr als 90 positiven Stimmen zu bearbeiten.
DMulligan
@AFinkelstein, ich denke, das macht diese Seite so großartig, dass Sie die Antwort mit der höchsten Bewertung bearbeiten können .
Sebastian
3
Diese Lösung behandelt nicht Wagenrücklauf (\ r) und Wagenrücklauf, gefolgt von einem Zeilenvorschub (\ r \ n)
Simon Brandhof - SonarSource
@ Simon Brandhof, ich bin verwirrt darüber, warum ein Wagenrücklauf als eine andere Zeile gezählt wird? Ein "\ n" ist ein Zeilenumbruch für den Wagenrücklauf. Wer also "\ r \ n" schreibt, versteht etwas nicht ... Außerdem sucht er char für char, sodass ich mir ziemlich sicher bin, ob jemand "\ r" verwenden würde \ n "es würde immer noch das" \ n "fangen und die Zeile zählen. Wie auch immer, ich denke, er hat den Punkt gut gemacht. Es gibt jedoch viele Szenarien, in denen dies nicht ausreicht, um eine Zeilenanzahl zu erhalten.
Nckbrz
22

Mit können Sie Streams verwenden:

try (Stream<String> lines = Files.lines(path, Charset.defaultCharset())) {
  long numOfLines = lines.count();
  ...
}
msayag
quelle
1
Code hat Fehler. Einfach, aber sehr langsam ... Versuchen Sie, meine Antwort unten (oben) zu lesen.
Ernestas Gruodis
12

Die Antwort mit der obigen Methode count () gab mir Zeilenfehler, wenn eine Datei am Ende der Datei keine neue Zeile hatte - die letzte Zeile in der Datei konnte nicht gezählt werden.

Diese Methode funktioniert besser für mich:

public int countLines(String filename) throws IOException {
    LineNumberReader reader  = new LineNumberReader(new FileReader(filename));
int cnt = 0;
String lineRead = "";
while ((lineRead = reader.readLine()) != null) {}

cnt = reader.getLineNumber(); 
reader.close();
return cnt;
}
Dave Bergert
quelle
In diesem Fall ist die Verwendung von LineNumberReader nicht erforderlich. Verwenden Sie einfach BufferedReader. In diesem Fall können Sie flexibel lange Datentypen verwenden cnt.
Syed Aqeel Ashiq
[INFO] PMD-Fehler: xx: 19 Regel: EmptyWhileStmt Priorität: 3 Vermeiden Sie leere while-Anweisungen.
Chhorn Elit
8

Ich weiß, dass dies eine alte Frage ist, aber die akzeptierte Lösung stimmte nicht ganz mit dem überein, wofür ich sie brauchte. Daher habe ich es verfeinert, um verschiedene Zeilenabschlüsse (und nicht nur Zeilenvorschub) zu akzeptieren und eine bestimmte Zeichencodierung (anstelle von ISO-8859- n ) zu verwenden. Alles in einer Methode (Refactor nach Bedarf):

public static long getLinesCount(String fileName, String encodingName) throws IOException {
    long linesCount = 0;
    File file = new File(fileName);
    FileInputStream fileIn = new FileInputStream(file);
    try {
        Charset encoding = Charset.forName(encodingName);
        Reader fileReader = new InputStreamReader(fileIn, encoding);
        int bufferSize = 4096;
        Reader reader = new BufferedReader(fileReader, bufferSize);
        char[] buffer = new char[bufferSize];
        int prevChar = -1;
        int readCount = reader.read(buffer);
        while (readCount != -1) {
            for (int i = 0; i < readCount; i++) {
                int nextChar = buffer[i];
                switch (nextChar) {
                    case '\r': {
                        // The current line is terminated by a carriage return or by a carriage return immediately followed by a line feed.
                        linesCount++;
                        break;
                    }
                    case '\n': {
                        if (prevChar == '\r') {
                            // The current line is terminated by a carriage return immediately followed by a line feed.
                            // The line has already been counted.
                        } else {
                            // The current line is terminated by a line feed.
                            linesCount++;
                        }
                        break;
                    }
                }
                prevChar = nextChar;
            }
            readCount = reader.read(buffer);
        }
        if (prevCh != -1) {
            switch (prevCh) {
                case '\r':
                case '\n': {
                    // The last line is terminated by a line terminator.
                    // The last line has already been counted.
                    break;
                }
                default: {
                    // The last line is terminated by end-of-file.
                    linesCount++;
                }
            }
        }
    } finally {
        fileIn.close();
    }
    return linesCount;
}

Diese Lösung ist in der Geschwindigkeit mit der akzeptierten Lösung vergleichbar und in meinen Tests etwa 4% langsamer (obwohl Timing-Tests in Java notorisch unzuverlässig sind).

Nathan Ryan
quelle
8

Ich habe die obigen Methoden zum Zählen von Linien getestet und hier sind meine Beobachtungen für verschiedene Methoden, die auf meinem System getestet wurden

Dateigröße: 1,6 GB Methoden:

  1. Scanner verwenden : ca. 35s
  2. Verwenden von BufferedReader : ca. 5s
  3. Mit Java 8 : 5s ca.
  4. Verwenden von LineNumberReader : ca. 5s

Darüber hinaus scheint der Java8- Ansatz recht praktisch zu sein:

Files.lines(Paths.get(filePath), Charset.defaultCharset()).count()
[Return type : long]
Anshul
quelle
5
/**
 * Count file rows.
 *
 * @param file file
 * @return file row count
 * @throws IOException
 */
public static long getLineCount(File file) throws IOException {

    try (Stream<String> lines = Files.lines(file.toPath())) {
        return lines.count();
    }
}

Getestet auf JDK8_u31. In der Tat ist die Leistung im Vergleich zu dieser Methode langsam:

/**
 * Count file rows.
 *
 * @param file file
 * @return file row count
 * @throws IOException
 */
public static long getLineCount(File file) throws IOException {

    try (BufferedInputStream is = new BufferedInputStream(new FileInputStream(file), 1024)) {

        byte[] c = new byte[1024];
        boolean empty = true,
                lastEmpty = false;
        long count = 0;
        int read;
        while ((read = is.read(c)) != -1) {
            for (int i = 0; i < read; i++) {
                if (c[i] == '\n') {
                    count++;
                    lastEmpty = true;
                } else if (lastEmpty) {
                    lastEmpty = false;
                }
            }
            empty = false;
        }

        if (!empty) {
            if (count == 0) {
                count = 1;
            } else if (!lastEmpty) {
                count++;
            }
        }

        return count;
    }
}

Getestet und sehr schnell.

Ernestas Gruodis
quelle
Das ist nicht richtig. Habe einige Experimente mit deinem Code gemacht und die Methode ist immer langsamer. Stream<String> - Time consumed: 122796351 Stream<String> - Num lines: 109808 Method - Time consumed: 12838000 Method - Num lines: 1Und die Anzahl der Zeilen ist sogar falsch
aw-think
Ich habe auf einem 32-Bit-Computer getestet. Vielleicht wären auf 64-Bit unterschiedliche Ergebnisse. Und es war der Unterschied 10 Mal oder mehr, wie ich mich erinnere. Könnten Sie den Text irgendwo posten, um die Zeile zu zählen? Sie können Notepad2 verwenden, um Zeilenumbrüche der Einfachheit halber anzuzeigen.
Ernestas Gruodis
Das könnte der Unterschied sein.
Aw-Think
Wenn Sie Wert auf Leistung legen, sollten BufferedInputStreamSie ohnehin kein verwenden, wenn Sie in Ihren eigenen Puffer lesen möchten. Selbst wenn Ihre Methode einen geringfügigen Leistungsvorteil aufweist, verliert sie an Flexibilität, da sie nicht mehr alleinige \rTerminatoren (altes MacOS) unterstützt und nicht jede Codierung unterstützt.
Holger
4

Ein einfacher Weg mit Scanner

static void lineCounter (String path) throws IOException {

        int lineCount = 0, commentsCount = 0;

        Scanner input = new Scanner(new File(path));
        while (input.hasNextLine()) {
            String data = input.nextLine();

            if (data.startsWith("//")) commentsCount++;

            lineCount++;
        }

        System.out.println("Line Count: " + lineCount + "\t Comments Count: " + commentsCount);
    }
Terry Bu
quelle
3

Ich kam zu dem Schluss, dass wc -l: s Methode zum Zählen von Zeilenumbrüchen in Ordnung ist, aber nicht intuitive Ergebnisse für Dateien zurückgibt, bei denen die letzte Zeile nicht mit einem Zeilenumbruch endet.

Die auf LineNumberReader basierende @ er.vikas-Lösung, bei der jedoch eine zur Zeilenanzahl hinzugefügt wurde, ergab nicht intuitive Ergebnisse für Dateien, bei denen die letzte Zeile mit einer neuen Zeile endet.

Ich habe daher ein Algo erstellt, das wie folgt funktioniert:

@Test
public void empty() throws IOException {
    assertEquals(0, count(""));
}

@Test
public void singleNewline() throws IOException {
    assertEquals(1, count("\n"));
}

@Test
public void dataWithoutNewline() throws IOException {
    assertEquals(1, count("one"));
}

@Test
public void oneCompleteLine() throws IOException {
    assertEquals(1, count("one\n"));
}

@Test
public void twoCompleteLines() throws IOException {
    assertEquals(2, count("one\ntwo\n"));
}

@Test
public void twoLinesWithoutNewlineAtEnd() throws IOException {
    assertEquals(2, count("one\ntwo"));
}

@Test
public void aFewLines() throws IOException {
    assertEquals(5, count("one\ntwo\nthree\nfour\nfive\n"));
}

Und es sieht so aus:

static long countLines(InputStream is) throws IOException {
    try(LineNumberReader lnr = new LineNumberReader(new InputStreamReader(is))) {
        char[] buf = new char[8192];
        int n, previousN = -1;
        //Read will return at least one byte, no need to buffer more
        while((n = lnr.read(buf)) != -1) {
            previousN = n;
        }
        int ln = lnr.getLineNumber();
        if (previousN == -1) {
            //No data read at all, i.e file was empty
            return 0;
        } else {
            char lastChar = buf[previousN - 1];
            if (lastChar == '\n' || lastChar == '\r') {
                //Ending with newline, deduct one
                return ln;
            }
        }
        //normal case, return line number + 1
        return ln + 1;
    }
}

Wenn Sie intuitive Ergebnisse wünschen, können Sie diese verwenden. Wenn Sie nur wc -lKompatibilität wünschen , verwenden Sie einfach die @ er.vikas-Lösung, fügen Sie jedoch keine zum Ergebnis hinzu und wiederholen Sie den Sprung:

try(LineNumberReader lnr = new LineNumberReader(new FileReader(new File("File1")))) {
    while(lnr.skip(Long.MAX_VALUE) > 0){};
    return lnr.getLineNumber();
}
Alexander Torstling
quelle
2

Wie wäre es mit der Process-Klasse aus Java-Code heraus? Und dann die Ausgabe des Befehls lesen.

Process p = Runtime.getRuntime().exec("wc -l " + yourfilename);
p.waitFor();

BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
int lineCount = 0;
while ((line = b.readLine()) != null) {
    System.out.println(line);
    lineCount = Integer.parseInt(line);
}

Müssen es aber versuchen. Wird die Ergebnisse veröffentlichen.

Sunil Shevante
quelle
1

Wenn Sie keine Indexstrukturen haben, können Sie die gesamte Datei nicht lesen. Sie können es jedoch optimieren, indem Sie vermeiden, es Zeile für Zeile zu lesen, und einen regulären Ausdruck verwenden, der allen Zeilenabschlusszeichen entspricht.

David Schmitt
quelle
Klingt nach einer ordentlichen Idee. Hat es jemand versucht und hat einen regulären Ausdruck dafür?
Willcodejavaforfood
1
Ich bezweifle, dass es eine so gute Idee ist: Es muss die gesamte Datei auf einmal gelesen werden (Martinus vermeidet dies) und reguläre Ausdrücke sind für eine solche Verwendung übertrieben (und langsamer) (einfache Suche nach festen Zeichen).
PhiLho
@will: was ist mit / \ n /? @PhiLo: Regex Executors sind hochoptimierte Leistungsmaschinen. Abgesehen von der Einschränkung, alles in den Speicher zu lesen, glaube ich nicht, dass eine manuelle Implementierung schneller sein kann.
David Schmitt
1

Diese lustige Lösung funktioniert wirklich gut!

public static int countLines(File input) throws IOException {
    try (InputStream is = new FileInputStream(input)) {
        int count = 1;
        for (int aChar = 0; aChar != -1;aChar = is.read())
            count += aChar == '\n' ? 1 : 0;
        return count;
    }
}
Ilya Gazman
quelle
0

Verwenden Sie auf Unix-basierten Systemen den wcBefehl in der Befehlszeile.

Peter Hilton
quelle
@IainmH, Ihr zweiter Vorschlag zählt nur die Anzahl der Einträge im aktuellen Verzeichnis. Nicht was beabsichtigt war? (oder vom OP angefordert)
Der archetypische Paul
@IainMH: das macht wc sowieso (Datei lesen, Zeilenende zählen).
PhiLho
@PhiLho Sie müssten den Schalter -l verwenden, um die Zeilen zu zählen. (Nicht wahr? - es ist eine Weile her)
Iain Holder
@ Paul - Sie haben natürlich 100% Recht. Meine einzige Verteidigung ist, dass ich das vor meinem Kaffee gepostet habe. Ich bin jetzt so scharf wie ein Knopf. : D
Iain Holder
0

Sie können nur wissen, wie viele Zeilen sich in der Datei befinden, indem Sie sie zählen. Sie können natürlich eine Metrik aus Ihren Daten erstellen, die eine durchschnittliche Länge von einer Zeile ergibt. Anschließend können Sie die Dateigröße ermitteln und diese durch den Durchschnitt teilen. Länge, aber das wird nicht genau sein.

Esko
quelle
1
Interessantes Downvote, egal welches Kommandozeilen-Tool Sie verwenden, alle machen sowieso das Gleiche, nur intern. Es gibt keinen magischen Weg, um die Anzahl der Zeilen herauszufinden, sie müssen von Hand gezählt werden. Sicher, es kann als Metadaten gespeichert werden, aber das ist eine ganz andere Geschichte ...
Esko
0

Bester optimierter Code für mehrzeilige Dateien ohne Zeilenumbruch ('\ n') bei EOF.

/**
 * 
 * @param filename
 * @return
 * @throws IOException
 */
public static int countLines(String filename) throws IOException {
    int count = 0;
    boolean empty = true;
    FileInputStream fis = null;
    InputStream is = null;
    try {
        fis = new FileInputStream(filename);
        is = new BufferedInputStream(fis);
        byte[] c = new byte[1024];
        int readChars = 0;
        boolean isLine = false;
        while ((readChars = is.read(c)) != -1) {
            empty = false;
            for (int i = 0; i < readChars; ++i) {
                if ( c[i] == '\n' ) {
                    isLine = false;
                    ++count;
                }else if(!isLine && c[i] != '\n' && c[i] != '\r'){   //Case to handle line count where no New Line character present at EOF
                    isLine = true;
                }
            }
        }
        if(isLine){
            ++count;
        }
    }catch(IOException e){
        e.printStackTrace();
    }finally {
        if(is != null){
            is.close();    
        }
        if(fis != null){
            fis.close();    
        }
    }
    LOG.info("count: "+count);
    return (count == 0 && !empty) ? 1 : count;
}
Pramod Yadav
quelle
0

Scanner mit Regex:

public int getLineCount() {
    Scanner fileScanner = null;
    int lineCount = 0;
    Pattern lineEndPattern = Pattern.compile("(?m)$");  
    try {
        fileScanner = new Scanner(new File(filename)).useDelimiter(lineEndPattern);
        while (fileScanner.hasNext()) {
            fileScanner.next();
            ++lineCount;
        }   
    }catch(FileNotFoundException e) {
        e.printStackTrace();
        return lineCount;
    }
    fileScanner.close();
    return lineCount;
}

Habe es nicht getaktet.

user176692
quelle
-2

wenn Sie dies verwenden

public int countLines(String filename) throws IOException {
    LineNumberReader reader  = new LineNumberReader(new FileReader(filename));
    int cnt = 0;
    String lineRead = "";
    while ((lineRead = reader.readLine()) != null) {}

    cnt = reader.getLineNumber(); 
    reader.close();
    return cnt;
}

Sie können nicht zu großen Zeilen laufen, mag 100.000 Zeilen, weil die Rückgabe von reader.getLineNumber int ist. Sie benötigen lange Datentypen, um maximale Zeilen zu verarbeiten.

Faisal
quelle
14
Ein intkann Werte von bis zu ungefähr 2 Milliarden halten. Wenn Sie eine Datei mit mehr als 2 Milliarden Zeilen laden, liegt ein Überlaufproblem vor. Wenn Sie jedoch eine nicht indizierte Textdatei mit mehr als zwei Milliarden Zeilen laden, haben Sie wahrscheinlich andere Probleme.
Adam Norberg