如何使用流读取文件时保留换行符 - java 8

A.R*_*K.S 9 java newline replaceall java-8 java-stream

      try (Stream<String> lines = Files.lines(targetFile)) {  
     List<String> replacedContent = lines.map(line ->  
                                       StringUtils.replaceEach(line,keys, values))
                                       .parallel()
                                       .collect(Collectors.toList());
    Files.write(targetFile, replacedContent);
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试替换文件的每一行中的多个文本模式.但我观察到"\ r \n"(字节等效10和13)正被替换为"\ r"(仅为10)并且我的比较测试失败了.

我想保留输入文件中的换行符,并且不希望java触及它们.任何人都可以建议是否有办法这样做而不必使用单独的默认替换"\ r \n".

Stu*_*rks 12

问题是Files.lines()在顶部实现BufferedReader.readLine(),它读取一行直到行终止符并将其抛弃.然后,当您使用类似的东西编写Files.write()行时,它会在每行之后提供系统特定的行终止符,这可能与读入的行终止符不同.

如果你真的想要完全保留行终止符,即使它们是不同行终止符的混合,你也可以使用正则表达式Scanner.

首先定义一个匹配包含有效行终止符或EOF的行的模式:

Pattern pat = Pattern.compile(".*\\R|.+\\z");
Run Code Online (Sandbox Code Playgroud)

\\R是一个特殊的换行符匹配器,它匹配常用的行终止符以及一些我从未听说过的Unicode行终止符.:-) (\\r\\n|\\r|\\n)如果你只想要通常的CRLF,CRLF终结器,你可以使用类似的东西.

您必须包含.+\\z以匹配文件中没有行终止符的潜在最后"行".确保正则表达式始终匹配至少一个字符,以便在扫描程序到达文件末尾时找不到匹配项.

然后,使用a读取行Scanner直到它返回null:

try (Scanner in = new Scanner(Paths.get(INFILE), "UTF-8")) {
    String line;
    while ((line = in.findWithinHorizon(pat, 0)) != null) {
        // Process the line, then write the output using something like
        // FileWriter.write(String) that doesn't add another line terminator.
    }
}
Run Code Online (Sandbox Code Playgroud)