如何忽略一些 Java 的 Files.lines 行尾分隔符



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

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

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

我的问题是,我让grep返回与其匹配的行号,但由于EOL分隔符的差异,如果我试图跳到grep返回的行号,Files.lines.skip(numLines)就不会与同一行对齐。

让我们假设您正在进行逐字节输入。。。

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

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可能会获得更好的性能,但它会使代码更加复杂。(如果您不熟悉BufferAPI。(
  3. 你可以用BufferedReader做类似的事情
  4. 对于生产质量代码,您应该使用try with resources来管理InputStream资源

试试这个。

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

最新更新