我遇到过这种情况,我正在读取一些日志文件,然后通过以下代码片段计算我遇到的行数。
byte[] c = new byte[1024];
long count = 0;
int readChars = 0;
while ((readChars = is.read(c)) != -1) {
for (int i = 0; i < readChars; ++i) {
if (c[i] == '\n') {
++count;
}
}
}
我的问题是,当我尝试读取文件(CSV,Syslog或任何其他野性格式)时,它运行得很好,并给我正确的结果。但是当我尝试运行一个通过mac生成的文件时,它会变成干线,只是报告回读了一行。
现在我的日志文件很大,我知道它有几千行日志,但它只读了一行。我在Sublime中打开了这个文件,我可以看到所有单独的行,但是当我通过VIM查看这个文件时,它只显示了一个带有字符的文件&#39; ^ M&#39;在每一行的末尾(我猜它是使用它作为行终止符)。
下面是两行的样本。您可以看到vim正在显示应该是新行的^ M字符
15122,25Dec2013,19:42:25,192.168.5.1,log,allow ,, eth0,outbound,Application Control ,, Network,Bob(+),Bob(+),,,, 59857d77 ,,,,,, ,, 570033 ,,,,,,,,,,,,, 192.168.5.7,176.32.96.190,TCP,80,56305,15606,554427,60461741,的 ** ,,,,, ,, 1,的 ** 下,的 ** 下,的 ** 下,的 ** 下,的 ** < / strong>, ** , ** , ** , ** ,其他:Wget / 1.13。 4(linux-gnu),其他:服务器,192.168.5.7,60461741:1 ,,,,,, ** , ** , ** < /strong>,,,,strong>**,,,,,^ M359,23Dec2013,18:54:03,192.168.5.1,log,allow,,eth0,outbound,Application Control ,, Network,Charlie(+ ),查理(+),,,, c0fa2dac ,,,,,,,, 1171362 ,,,,,,,,,,,,, 192.168.5.6,205.251.242.54,TCP,80,45483,31395,1139967 ,60340847,的 ** ,,,,,,, 2,的 ** 下,的 ** 下,的 ** , ** 下,的 ** 下,的 ** 下,的 ** 下,的 ** , ** 下,行吟r:Wget / 1.13.4(linux-gnu),其他:服务器,192.168.5.6,60340847:1 ,,,,,,, ** , ** , ** ,,,的 ** ,,,, ^ M
有关如何解决此问题的任何建议?
答案 0 :(得分:5)
甚至在你换行之前的第一个问题是你正在阅读 bytes 然后将它们视为字符。您实际上正在假设ISO-8859-1的编码可能不正确。您应该使用InputStreamReader
代替。
然后是操作系统具有不同换行符的问题...使用BufferedReader.readLine()
以处理\n
,\r
或{{1的换行符的方式读取一行}}
所以你的代码会变成:
\r\n
答案 1 :(得分:1)
换行(^J
,0x0a)和回车(^M
,0x0d)都用作行分隔符; Unix使用第一个,(旧)Mac,后者,Windows两者结合使用(CR-LF)。
如果你没有文件输入库来抽象它(如果你必须支持旧的Mac格式(作为新的MacOS,因为内核是基于Unix的,也使用LF)),将LF和CR都视为行分隔符,并且不要对Windows使用的CR-LF进行两次计数。
Vim检测到的内容由'fileformats'
选项决定。您也可以通过
:set fileformats+=mac