我认为发生了以下情况
包含 ^L (ff) 的所有行都被修改以删除 ^L 之前的所有内容,但此外,您在 1 中的副作用是所有 \r (cr) 也被删除。但是,如果 cr 出现在 ^L nextLine() 之前,也将其视为一行。请注意,在下面的输出文件中,输入文件中 cr + nl 的数量是 6,而 cr + nl 的数量也是 6,但它们都是 nl,因此带有 c 的行被保留,因为它正在被处理与 ^L 不同的行。可能不是你想要的。见下文。
一些观察
源文件正在使用 \r\n 定义新行的系统上生成,而您的程序正在不使用的系统上运行。因此,所有出现的 0xd 都将被删除。即使没有^L,这也会使两个文件大小不同。
但是您可能忽略了 #1,因为 vim 将在 DOS 模式下运行(将 \r\n 识别为换行符)或非 DOS 模式(仅 \n),这取决于它在打开文件时读取的内容并隐藏了事实用户如果可以的话。事实上,为了测试,我不得不在 \r 中使用 ^v^m 进行暴力破解,因为我在 Linux 上使用 vim more here进行编辑。
您的测试方法可能是使用 od -x (十六进制正确)?但这输出的整数不是你想要的。考虑以下输入文件和输出文件。在你的程序运行之后。在 vi 中查看
输入文件
a
b^M
c^M^M ^L
d^L
输出文件
a
b
c
好吧,也许这是对的,让我们看看 od 要说什么
输入文件的 od -x
0a61 0d62 630a 0d0d 0c20 640a 0a0c
输出文件的 od -x
0a61 0a62 0a63 0a0a 000a
咦,那个null是从哪里来的?但是从 od 的手册页等待
-t type Specify the output format. type is a string containing one or more of the following kinds of type specifiers:
q a Named characters (ASCII). Control characters are displayed using the following names:
-h, -x Output hexadecimal shorts. Equivalent to -t x2.
-a Output named characters. Equivalent to -t a.
哦,好的,所以改用 -a 选项
od -a 输入
a nl b cr nl c cr cr sp ff nl d ff nl
od -a 输出
a nl b nl c nl nl nl nl
强制 java 忽略 \r
最后,话虽如此,您确实必须克服对 java 的隐含理解,即 \r 分隔一行,甚至与文档相反。即使明确设置扫描仪使用忽略模式,它仍然与文档相反,您必须通过设置分隔符再次覆盖它(见下文)。我发现以下内容可能会通过坚持 Unix 行语义来满足您的要求。我还添加了一些逻辑以不输出空行。
public static void repl(File original,File file) throws IOException
{
Scanner fileScanner = new Scanner(original);
Pattern pattern1 = Pattern.compile("(?d).*");
fileScanner.useDelimiter("(?d)\\n");
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
while(fileScanner.hasNext(pattern1))
{
String next = fileScanner.next(pattern1);
next = next.replaceAll("(?d)(.*\\x0C)|(\\x0D)","");
if(next.length() != 0)
{
out.write(next);
out.newLine();
}
}
out.flush();
out.close();
}
随着这一变化,上面的输出变为。
od -a 输入
a nl b cr nl c cr cr sp ff nl d ff nl
od -a 输出
a nl b nl