使用 BufferedReader 跳过一行(跳过,但不阅读)

Skip a line using BufferedReader (skip, but not read it)

大家好,我目前正在使用 BufferedReader 读取文件。我有类似的东西:

br.readLine() != null

对于每个调用循环。

现在如果我想跳过一行我该怎么办。在这里,我阅读了其他人发布的几个类似问题,其中大多数建议使用 readLine().

我知道调用 readLine() 一次会使指针指向下一行。但这不是首选,因为我正在考虑这里的阅读性能。虽然你好像跳过了一行,但实际上系统已经读过了,所以不是时间效率。我想要的是将指针移动到下一行,而不是阅读它。

有什么好主意吗?

不看就不能跳过这行

为了知道跳到哪里,你必须知道下一个换行符在哪里,所以你必须阅读它。

P.S。除非你有充分的理由不这样做,否则 BufferedReader 应该适合你——它非常高效

一般来说,任何语言和任何API都不可能。

要跳过一行,您需要知道下一行的偏移量。要么您有一种文件格式可以为您提供该信息,您将获得行偏移量作为输入,要么您需要读取每个字节才能知道一行何时结束以及下一行何时开始。

你看过readLine()的代码了吗?它一个一个地读取字符,直到找到 \r 或 \n 并将它们附加到 StringBuffer 中。您想要的是无需创建 StringBuffer 的负担的这种行为。只需覆盖 class BufferedReader 并提供您自己的实现,它只读取字符直到 /r 或 /n 而无需构建无用的字符串。

我看到的唯一问题是许多字段是私有的...

如果你关心中间浪费的内存StringBuffer,你可以试试下面的实现:

public static void skipLine(BufferedReader br) throws IOException {
    while(true) {
        int c = br.read();
        if(c == -1 || c == '\n')
            return;
        if(c == '\r') {
            br.mark(1);
            c = br.read();
            if(c != '\n')
                br.reset();
            return;
        }
    }
}

它似乎适用于 readLine'\n''\r''\r\n')支持的所有 EOL。

作为替代方案,您可以扩展 BufferedReader class 添加此方法作为其中的实例方法。

您有时会遇到跳过第一行代码分析工具(声纳等)的问题,抱怨您没有使用该值。对于 CSV,如果第一行 headers,您可能希望跳过(即不使用)第一行。在这种情况下,您可以流式传输并跳过这些行吗?

try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
  Stream<String> lines = reader.lines().skip(1);

  lines.forEachOrdered(line -> {

  ...
  });
}