如何忽略某些 Java 的 Files.lines 行尾定界符

How to ignore some of Java's Files.lines end-of-line delimiters

Java 的 Files.lines 方法将文件中的所有行作为流读取,将文件分成以下分隔符处的行:

\u000D followed by \u000A, CARRIAGE RETURN followed by LINE FEED
\u000A, LINE FEED
\u000D, CARRIAGE RETURN

我的文件包含 \u000D, CARRIAGE RETURN 的奇怪出现,我 not 想将其视为新行,以与 grep ( Windows) 不会只将单个 \u000D 视为换行符。我想将文件中的行作为流处理,但是有没有一种方法可以获得不使用单个 \u000D 作为换行标记的流,仅使用 CR/LF 或 LF?我必须使用 Java 8.

我的问题是我正在 grep 到 return 行号及其匹配项,但是由于 EOL 定界符的不同,Files.lines.skip(numLines) 不会与同一行对齐,如果我尝试跳到由 grep.

编辑的行号 return

试试这个。

Stream.of(Files.readString(path).split("\r?\n"))
    .filter(...

假设您正在进行按字节输入...

可扩展/高效的解决方案避免将整个文件保存在内存中,和/或为您跳过的每一行输入创建一个字符串对象。这是一种方法。

File f = ...
InputStream is = new BufferedInputStream(new FileInputStream(f));
int lineCounter = 1;
int wantedLine = 42;
int b = 0;
while (lineCounter < wantedLine && b != -1) {
    do {
        b = is.read();
        if (b == '\n') {
            lineCount++;
        }
    } while (b != -1 && b != '\n');
}
if (lineCounter == wantedLine) {
    // do stuff
}

备注:

  1. 我知道这有点笨拙。并且有可能取消嵌套循环......但这段代码旨在“说明”一种方法。
  2. 使用 ByteBuffer 可能会获得更好的性能,但它会使代码更加复杂。 (如果您不熟悉 Buffer API。)
  3. 你可以用 BufferedReader 做类似的事情。
  4. 对于生产质量代码,您应该使用尝试使用资源来管理InputStream资源。