Số dòng trong một tệp trong Java


213

Tôi sử dụng các tệp dữ liệu khổng lồ, đôi khi tôi chỉ cần biết số lượng dòng trong các tệp này, thông thường tôi mở chúng ra và đọc từng dòng cho đến khi tôi đến cuối tệp

Tôi đã tự hỏi nếu có một cách thông minh hơn để làm điều đó

Câu trả lời:


237

Đây là phiên bản nhanh nhất tôi tìm thấy cho đến nay, nhanh hơn khoảng 6 lần so với readLines. Trên tệp nhật ký 150 MB, việc này mất 0,35 giây, so với 2,40 giây khi sử dụng readLines (). Để giải trí, lệnh wc -l của linux mất 0,15 giây.

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 năm rưỡi sau: Tôi thực tế không có kinh nghiệm về java, nhưng dù sao tôi cũng đã cố gắng đánh giá mã này theo LineNumberReadergiải pháp bên dưới vì nó làm phiền tôi rằng không ai làm điều đó. Dường như đối với các tệp lớn, giải pháp của tôi nhanh hơn. Mặc dù có vẻ như phải mất một vài lần chạy cho đến khi trình tối ưu hóa thực hiện công việc tốt. Tôi đã chơi một chút với mã và đã tạo ra một phiên bản mới luôn nhanh nhất:

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

Điểm chuẩn nối lại cho tệp văn bản 1,3 GB, trục y trong vài giây. Tôi đã thực hiện 100 lần chạy với cùng một tệp và đo từng lần chạy với System.nanoTime(). Bạn có thể thấy rằng countLinesOldcó một vài ngoại lệ, và countLinesNewkhông có gì và trong khi nó chỉ nhanh hơn một chút, sự khác biệt có ý nghĩa thống kê. LineNumberReaderrõ ràng là chậm hơn.

Sơ đồ điểm chuẩn


5
BufferedInputStream sẽ thực hiện việc đệm cho bạn, vì vậy tôi không thấy việc sử dụng một mảng byte [] trung gian sẽ làm cho nó nhanh hơn như thế nào. Dù sao thì bạn cũng không thể làm tốt hơn nhiều so với việc sử dụng readLine () nhiều lần (vì điều đó sẽ được tối ưu hóa theo API).
WDS

54
Bạn sẽ đóng InputStream khi bạn hoàn thành nó, phải không?
uốn cong vào

5
Nếu bộ đệm giúp nó sẽ vì BufferedInputStream đệm 8K theo mặc định. Tăng byte của bạn [] lên kích thước này hoặc lớn hơn và bạn có thể thả BufferedInputStream. ví dụ: thử 1024 * 1024 byte.
Peter Lawrey

8
Hai điều: (1) Định nghĩa của bộ kết thúc dòng trong nguồn Java là trả về vận chuyển, nguồn cấp dữ liệu hoặc trả về vận chuyển theo sau là nguồn cấp dữ liệu. Giải pháp của bạn sẽ không hoạt động đối với CR được sử dụng như một đầu cuối dòng. Cấp, hệ điều hành duy nhất mà tôi có thể nghĩ rằng sử dụng CR làm đầu cuối dòng mặc định là Mac OS trước Mac OS X. (2) Giải pháp của bạn giả định mã hóa ký tự như US-ASCII hoặc UTF-8. Số lượng dòng có thể không chính xác cho các bảng mã như UTF-16.
Nathan Ryan

2
Mã tuyệt vời ... cho tệp văn bản 400mb, chỉ mất một giây. Cảm ơn rất nhiều @martinus
user3181500

199

Tôi đã thực hiện một giải pháp khác cho vấn đề này, tôi thấy nó hiệu quả hơn trong việc đếm hàng:

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
}

LineNumberReaderTrường của nó lineNumberlà một số nguyên ... Không phải nó chỉ bao bọc cho các tệp dài hơn Integer.MAX_VALUE? Tại sao phải bỏ qua một thời gian dài ở đây?
epb

1
Thêm một vào số đếm thực sự không chính xác. wc -lđếm số lượng ký tự dòng mới trong tệp. Điều này hoạt động vì mỗi dòng được kết thúc bằng một dòng mới, bao gồm cả dòng cuối cùng trong một tệp. Mỗi dòng có một ký tự dòng mới, bao gồm các dòng trống, do đó số lượng ký tự dòng mới == số dòng trong một tệp. Bây giờ, lineNumberbiến trong FileNumberReadercũng đại diện cho số ký tự dòng mới nhìn thấy. Nó bắt đầu từ 0, trước khi bất kỳ dòng mới nào được tìm thấy và được tăng lên với mỗi dòng char mới được nhìn thấy. Vì vậy, đừng thêm một vào số dòng xin vui lòng.
Alexander Torstling

1
@PB_MLT: Mặc dù bạn đúng rằng một tệp có một dòng không có dòng mới sẽ được báo cáo là 0 dòng, đây cũng là cách wc -lbáo cáo loại tệp này. Đồng thời xem stackoverflow.com/questions/729692/
Mạnh

@PB_MLT: Bạn gặp vấn đề ngược lại nếu tệp chỉ bao gồm một dòng mới. Thuật toán được đề xuất của bạn sẽ trả về 0 và wc -lsẽ trả về 1. Tôi đã kết luận rằng tất cả các phương pháp đều có sai sót và đã thực hiện một phương pháp dựa trên cách tôi muốn nó hành xử, xem câu trả lời khác của tôi ở đây.
Alexander Torstling 16/2/2016

3
Tôi đã bỏ phiếu phản hồi này, vì dường như không ai trong số các bạn đã đánh giá nó
amstegraf

30

Câu trả lời được chấp nhận có một lỗi đối với các tệp đa dòng không kết thúc ở dòng mới. Một tệp một dòng kết thúc mà không có dòng mới sẽ trả về 1, nhưng một tệp hai dòng kết thúc mà không có dòng mới cũng sẽ trả về 1. Đây là một triển khai của giải pháp được chấp nhận để khắc phục điều này. Việc kiểm tra endWithoutNewLine gây lãng phí cho tất cả mọi thứ trừ lần đọc cuối cùng, nhưng nên là thời gian không đáng kể so với chức năng tổng thể.

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

6
Nắm bắt tốt. Không chắc chắn tại sao bạn không chỉ chỉnh sửa câu trả lời được chấp nhận và ghi chú trong một nhận xét. Hầu hết mọi người sẽ không đọc đến đây.
Ryan

@Ryan, thật không đúng khi chỉnh sửa câu trả lời được chấp nhận 4 năm tuổi với hơn 90 lượt upvote.
DMulligan

@AFinkelstein, tôi cảm thấy đó là điều làm cho trang web này trở nên tuyệt vời, rằng bạn có thể chỉnh sửa câu trả lời được bình chọn hàng đầu.
Sebastian

3
Giải pháp này không xử lý trả lại vận chuyển (\ r) và trả lại vận chuyển theo sau là một nguồn cấp dữ liệu (\ r \ n)
Simon Brandhof - SonarSource

@Simon Brandhof, tôi bối rối về lý do tại sao tiền gửi xe ngựa sẽ được tính là một dòng khác? "\ N" là nguồn cấp dữ liệu dòng trả về Vận chuyển, vì vậy bất cứ ai viết "\ r \ n" đều không hiểu điều gì đó ... Ngoài ra, anh ta đang tìm kiếm char bằng char, vì vậy tôi khá chắc chắn nếu có ai đó sử dụng "\ r \ n "nó vẫn sẽ bắt được" \ n "và đếm dòng. Dù bằng cách nào, tôi nghĩ rằng anh ấy đã đưa ra quan điểm tốt. Tuy nhiên, chúng là nhiều tình huống trong đó đây không phải là một cách đủ để có được số lượng dòng.
nckbrz

22

Với , bạn có thể sử dụng luồng:

try (Stream<String> lines = Files.lines(path, Charset.defaultCharset())) {
  long numOfLines = lines.count();
  ...
}

1
Mã có lỗi. Đơn giản, nhưng rất chậm ... Hãy thử nhìn vào câu trả lời của tôi bên dưới (ở trên).
Ernestas Gruodis

12

Câu trả lời với số phương thức () ở trên đã cho tôi biết các dòng sai nếu một tệp không có dòng mới ở cuối tệp - không thể đếm được dòng cuối cùng trong tệp.

Phương pháp này hoạt động tốt hơn đối với tôi:

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

Trong trường hợp này, không cần sử dụng LineNumberReader, chỉ cần sử dụng BufferedReader, trong trường hợp đó bạn có thể linh hoạt sử dụng kiểu dữ liệu dài cho cnt.
Syed Aqeel Ashiq

[INFO] Lỗi PMD: xx: 19 Quy tắc: EmptyWhileStmt Ưu tiên: 3 Tránh trống trong khi báo cáo.
Chhorn Elit

8

Tôi biết đây là một câu hỏi cũ, nhưng giải pháp được chấp nhận không hoàn toàn khớp với những gì tôi cần nó làm. Vì vậy, tôi đã tinh chỉnh nó để chấp nhận các đầu cuối dòng khác nhau (thay vì chỉ cung cấp dòng) và sử dụng mã hóa ký tự được chỉ định (thay vì ISO-8859- n ). Tất cả trong một phương thức (tái cấu trúc khi thích hợp):

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

Giải pháp này có thể so sánh về tốc độ với giải pháp được chấp nhận, chậm hơn khoảng 4% trong các thử nghiệm của tôi (mặc dù các thử nghiệm thời gian trong Java nổi tiếng là không đáng tin cậy).


8

Tôi đã thử nghiệm các phương pháp trên để đếm các dòng và đây là những quan sát của tôi về các phương pháp khác nhau như được thử nghiệm trên hệ thống của tôi

Kích thước tệp: Phương pháp 1.6 Gb:

  1. Sử dụng Máy quét : khoảng 35 giây
  2. Sử dụng BufferedReader : khoảng 5 giây
  3. Sử dụng Java 8 : 5s khoảng
  4. Sử dụng LineNumberReader : khoảng 5 giây

Hơn nữa, Cách tiếp cận Java8 có vẻ khá tiện dụng:

Files.lines(Paths.get(filePath), Charset.defaultCharset()).count()
[Return type : long]

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

Đã thử nghiệm trên JDK8_u31. Nhưng thực sự hiệu suất chậm so với phương pháp này:

/**
 * 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;
    }
}

Đã thử nghiệm và rất nhanh.


Điều này không đúng. Thực hiện một số thử nghiệm với mã của bạn và phương pháp luôn chậm hơn. Stream<String> - Time consumed: 122796351 Stream<String> - Num lines: 109808 Method - Time consumed: 12838000 Method - Num lines: 1Và số lượng dòng thậm chí còn sai
aw-think

Tôi đã thử nghiệm trên máy 32 bit. Có lẽ trên 64-bit sẽ là kết quả khác nhau .. Và đó là sự khác biệt 10 lần trở lên như tôi nhớ. Bạn có thể gửi văn bản để đếm dòng ở đâu đó? Bạn có thể sử dụng Notepad2 để xem ngắt dòng cho thuận tiện.
Ernestas Gruodis 27/2/2015

Đó có thể là sự khác biệt.
aw-think

Nếu bạn quan tâm đến hiệu suất, bạn không nên sử dụng BufferedInputStreamkhi bạn sẽ đọc vào bộ đệm của riêng bạn. Ngoài ra, ngay cả khi phương thức của bạn có thể có một lợi thế hiệu suất nhỏ, nó sẽ mất tính linh hoạt, vì nó không hỗ trợ các \rđầu cuối dòng duy nhất (MacOS cũ) nữa và không hỗ trợ mọi mã hóa.
Holger

4

Một cách đơn giản bằng cách sử dụng Máy quét

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

3

Tôi đã kết luận rằng wc -l: phương pháp đếm dòng mới là tốt nhưng trả về kết quả không trực quan trên các tệp trong đó dòng cuối cùng không kết thúc bằng dòng mới.

Và giải pháp @ er.vikas dựa trên LineNumberReader nhưng việc thêm một vào số lượng dòng trả về kết quả không trực quan trên các tệp trong đó dòng cuối cùng kết thúc bằng dòng mới.

Do đó, tôi đã tạo ra một thuật toán xử lý như sau:

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

Và nó trông như thế này:

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

Nếu bạn muốn kết quả trực quan, bạn có thể sử dụng này. Nếu bạn chỉ muốn wc -ltương thích, hãy sử dụng giải pháp @ er.vikas đơn giản, nhưng không thêm một kết quả vào kết quả và thử lại bỏ qua:

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

2

Làm thế nào về việc sử dụng lớp Process từ bên trong mã Java? Và sau đó đọc đầu ra của lệnh.

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

Cần phải thử nó mặc dù. Sẽ đăng kết quả.


1

Nếu bạn không có bất kỳ cấu trúc chỉ mục nào, bạn sẽ không thể đọc được tập tin hoàn chỉnh. Nhưng bạn có thể tối ưu hóa nó bằng cách tránh đọc từng dòng một và sử dụng biểu thức chính quy để khớp với tất cả các đầu cuối dòng.


Âm thanh như một ý tưởng gọn gàng. Bất cứ ai đã thử nó và có một regrec cho nó?
willcodejavaforfood

1
Tôi nghi ngờ đó là một ý tưởng tốt: nó sẽ cần phải đọc toàn bộ tệp cùng một lúc (martinus tránh điều này) và regexes là quá mức cần thiết (và chậm hơn) cho việc sử dụng đó (tìm kiếm đơn giản các char cố định).
PhiLho

@will: còn / \ n /? @PhiLo: Regex Executors là những cỗ máy hiệu năng được điều chỉnh cao. Ngoại trừ cảnh báo đọc mọi thứ vào bộ nhớ, tôi không nghĩ rằng việc thực hiện thủ công có thể nhanh hơn.
David Schmitt

1

Giải pháp hài hước này hoạt động thực sự tốt!

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

0

Trên các hệ thống dựa trên Unix, sử dụng wclệnh trên dòng lệnh.


@IainmH, đề xuất thứ hai của bạn chỉ đếm số lượng mục trong thư mục hiện tại. Không phải những gì đã được dự định? (hoặc được OP yêu cầu)
Archetypal Paul

@IainMH: đó là những gì wc vẫn làm (đọc tệp, đếm kết thúc dòng).
PhiLho

@PhiLho Bạn sẽ phải sử dụng công tắc -l để đếm các dòng. (Không phải bạn? - đã được một lúc rồi)
Người giữ Iain

@Paul - bạn tất nhiên đúng 100%. Bảo vệ duy nhất của tôi là tôi đã đăng nó trước khi cà phê của tôi. Tôi sắc như một nút bây giờ. : D
Người giữ Iain

0

Cách duy nhất để biết có bao nhiêu dòng trong tệp là đếm chúng. Tất nhiên bạn có thể tạo một số liệu từ dữ liệu của mình, cung cấp cho bạn độ dài trung bình của một dòng và sau đó lấy kích thước tệp và chia số đó với avg. chiều dài nhưng điều đó sẽ không chính xác.


1
Downvote thú vị, cho dù bạn đang sử dụng công cụ dòng lệnh nào, tất cả đều LÀM NHỮNG CÂU CHUYỆN NÀY, chỉ trong nội bộ. Không có cách kỳ diệu nào để tìm ra số lượng dòng, chúng phải được đếm bằng tay. Chắc chắn nó có thể được lưu dưới dạng siêu dữ liệu nhưng đó là một câu chuyện hoàn toàn khác ...
Esko

0

Mã được tối ưu hóa tốt nhất cho các tệp nhiều dòng không có ký tự dòng mới ('\ n') tại 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;
}

0

Máy quét với 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;
}

Không theo dõi nó.


-2

nếu bạn sử dụng cái này

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

bạn không thể chạy đến các hàng num lớn, thích các hàng 100K, vì trả về từ reader.getLineNumber là int. bạn cần loại dữ liệu dài để xử lý các hàng tối đa ..


14
An intcó thể giữ các giá trị lên tới, xấp xỉ 2 tỷ. Nếu bạn đang tải một tệp có hơn 2 tỷ dòng, bạn có vấn đề tràn. Điều đó nói rằng, nếu bạn đang tải một tệp văn bản chưa được mã hóa với hơn hai tỷ dòng, bạn có thể gặp các vấn đề khác.
Adam Norberg
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.