我使用巨大的数据文件,有时我只需要知道这些文件中的行数,通常我打开它们,一行一行地读取它们,直到我到达文件的末尾

我在想有没有更聪明的办法


当前回答

似乎有几种不同的方法可以使用LineNumberReader。

我是这样做的:

int lines = 0;

FileReader input = new FileReader(fileLocation);
LineNumberReader count = new LineNumberReader(input);

String line = count.readLine();

if(count.ready())
{
    while(line != null) {
        lines = count.getLineNumber();
        line = count.readLine();
    }
    
    lines+=1;
}
    
count.close();

System.out.println(lines);

更简单的是,可以使用Java BufferedReader lines()方法返回元素流,然后使用stream count()方法对所有元素进行计数。然后只需在输出中添加1,就可以得到文本文件中的行数。

为例:

FileReader input = new FileReader(fileLocation);
LineNumberReader count = new LineNumberReader(input);

int lines = (int)count.lines().count() + 1;
    
count.close();

System.out.println(lines);

其他回答

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

在JDK8_u31上测试。但与此方法相比,性能确实较慢:

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

经过测试,非常快。

上面的count()方法给出的答案是,如果文件末尾没有换行符,就会出现行数错误——它无法计算文件中的最后一行。

这个方法更适合我:

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

在基于unix的系统上,在命令行上使用wc命令。

我测试了上面的方法来计数行,这里是我对不同方法的观察,在我的系统上进行了测试

文件大小:1.6 Gb 方法:

使用扫描仪:大约35秒 使用BufferedReader:大约5s 使用Java 8: 5s左右 使用LineNumberReader:大约5s

此外,Java8方法似乎非常方便:

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

要知道文件里有多少行,唯一的方法就是数数。当然,你可以从你的数据中创建一个指标,给你一个平均长度的一行,然后得到文件大小,并除以平均长度,但这不会是准确的。