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
}
注:
- 我知道这有点笨重。并且可以取消嵌套循环。。。但该代码旨在";说明性的";一种方法
- 使用
ByteBuffer
可能会获得更好的性能,但它会使代码更加复杂。(如果您不熟悉Buffer
API。( - 你可以用
BufferedReader
做类似的事情 - 对于生产质量代码,您应该使用try with resources来管理
InputStream
资源
试试这个。
Stream.of(Files.readString(path).split("r?n"))
.filter(...