java - Java中文件中的行数

标签 java large-files line-numbers

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

我想知道是否有更聪明的方法来做到这一点

最佳答案

这是迄今为止我发现的最快的版本,比 readLines 快大约 6 倍。在 150MB 的日志文件上,这需要 0.35 秒,而使用 readLines() 时需要 2.40 秒。只是为了好玩,linux的 wc -l 命令需要 0.15 秒。

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

编辑,9 1/2 年后:我几乎没有 Java 经验,但无论如何我尝试将此代码与下面的 LineNumberReader 解决方案进行基准测试,因为它困扰着我,没有人这样做。似乎特别是对于大文件,我的解决方案更快。尽管在优化器完成体面的工作之前似乎需要运行几次。我对代码进行了一些尝试,并生成了一个始终最快的新版本:

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

1.3GB 文本文件的基准测试结果,y 轴以秒为单位。我用同一个文件运行了 100 次,并用 System.nanoTime() 测量了每次运行。您可以看到 countLinesOld 有一些异常值,而 countLinesNew 没有,虽然它只是快一点,但差异在统计上是显着的。 LineNumberReader 显然更慢。

Benchmark Plot

关于java - Java中文件中的行数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/453018/

相关文章:

c# - 提高流式传输大型 (1-10 GB) 文件的速度 .Net Core

java - 获取打印行只打印一次并打印文件的行号

java - Spring java代码表单发布并重定向到不同的服务器

java - @Cacheable 和 @CachePut 不同的返回类型

csv - 如何在 GNU Octave 中加速读取大文件?

github - electron.exe 和 Github

java - 如何将 bean 对象放入 sessionMap,然后使用 Struts 2 属性标记在 jsp 页面上检索其属性

java - 在 Oracle 数据库中插入 byte[] 数组作为 blob 得到 ORA-01460 : unimplemented or unreasonable conversion requested

eclipse - 有没有办法从 eclipse 复制代码,包括 ine 数字

javascript - exception.lineNumber 在谷歌浏览器和 Internet Explorer 中返回 "undefined"