java - 跨不同操作系统读取换行符

标签 java vim file-io

我遇到过一种情况,我正在读取一些日志文件,然后通过以下代码片段计算我遇到的行数。

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 查看这个文件时,它只显示一个文件,每行末尾都有一个字符“^M”(我猜它是正在使用它作为行终止符)。

下面是两行的示例。您可以看到 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,**,**,**,**,**,**,**,**,**,Other: Wget/1.13.4 (linux-gnu),Other: Server,192.168.5.7,60461741:1,,,,,,**,**,**,,,**,,,,^M359,23Dec2013,18:54:03,192.168.5.1,log,allow,,eth0,outbound,Application Control,,Network,Charlie(+),Charlie(+),,,,c0fa2dac,,,,,,,,1171362,,,,,,,,,,,,,192.168.5.6,205.251.242.54,tcp,80,45483,31395,1139967,60340847,**,,,,,,,2,**,**,**,**,**,**,**,**,**,Other: Wget/1.13.4 (linux-gnu),Other: Server,192.168.5.6,60340847:1,,,,,,,**,**,**,,,**,,,,^M

关于如何解决这个问题有什么建议吗?

最佳答案

即使在换行之前,第一个问题是您正在读取字节,然后将它们视为字符。您实际上假设了 ISO-8859-1 编码,这很可能不正确。您应该使用 InputStreamReader相反。

然后是操作系统具有不同换行符的问题...使用 BufferedReader.readLine()以处理 \n 换行符的方式读取一行, \r\r\n .

所以你的代码将变成:

int count = 0;
try (BufferedReader reader = new BufferedReader(
     new InputStreamReader(is, charset))) {
   while (reader.readLine() != null) {
       count++;
   }
}

关于java - 跨不同操作系统读取换行符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23467913/

相关文章:

java - 使用 Xalan APi 2.7.1 进行 XSLT 处理

vim - 行号列表作为vim的输入

c - 如何在 C 中一次性提供第一个输入文件的输出作为第二个输入文件?

c++ - 将文件输出到特定文件夹 C++ Windows 7

java - 当我尝试在 net-beans 中运行它时,我收到 "java.lang.reflect.InvocationTargetException"。为什么会发生这种情况?

Java代码读取网站内容

java - 通用 BinarySearchTree 中的 PostOrder 输出 (Java)

vim - 通过IdeaVim在IntelliJ中使用Vim插件

c++ - 准备 vim 环境以使用 clang-format

java File mkdirs 和 createNewFile 将不起作用