首页 > 解决方案 > java无法从文件中读取一行

问题描述

我正在使用以下代码读取文件:

 Scanner in = new Scanner(new File(fileName));
    while (in.hasNextLine()) {
        String[] line = in.nextLine().trim().split("[ \t]");
       .
       .
       .
    }

当我用 vim 打开文件时,有些行以以下特殊字符开头:

在此处输入图像描述

但java代码无法读取这些行。当它到达这些行时,它认为它是文件的结尾并且 hasNextLine() 函数返回 false !

编辑:这是提到的(有问题的)行的十六进制转储:

0000000:e280 9c20 302e 3230 3133 3220 302e 3231 ... 0.20132 0.21 0000010:3431 392d 302e 3034 0a 419-0.04。

标签: javajava-8eofunexpectendoffile

解决方案


@VGR 做对了。

tl;博士:使用Scanner in = new Scanner(new File(fileName), "ISO-8859-1");

似乎正在发生的是:

  • 由于那个单独的 0x9C 字符,您的文件不是有效的 UTF-8。
  • 扫描仪正在以 UTF-8 格式读取文件,因为这是系统默认设置
  • 底层库抛出一个MalformedInputException
  • 扫描仪捕捉并隐藏它(一个善意但被误导的设计决定)
  • 它开始报告它没有更多的行
  • 除非你真的问扫描仪,否则你不会知道有什么问题

这是一个 MCVE:

import java.io.*;
import java.util.*;

class Test {
  public static void main(String[] args) throws Exception {
    Scanner in = new Scanner(new File(args[0]), args[1]);
    while (in.hasNextLine()) {
      String line = in.nextLine();
      System.out.println("Line: " + line);
    }
    System.out.println("Exception if any: " + in.ioException());
  }
}

这是一个正常调用的示例:

$ printf 'Hello\nWorld\n' > myfile && java Test myfile UTF-8
Line: Hello
Line: World
Exception if any: null

这是您所看到的(除了您没有检索并显示隐藏的异常)。请特别注意,没有显示任何行:

$ printf 'Hello\nWorld \234\n' > myfile && java Test myfile UTF-8
Exception if any: java.nio.charset.MalformedInputException: Input length = 1

这是当解码为 ISO-8859-1 时,所有字节序列都有效的解码(即使 0x9C 没有分配的字符,因此不会显示在终端中):

$ printf 'Hello\nWorld \234\n' > myfile && java Test myfile ISO-8859-1
Line: Hello
Line: World
Exception if any: null

如果您只对 ASCII 数据感兴趣并且没有任何 UTF-8 字符串,您可以ISO-8859-1通过将其作为第二个参数传递给Scanner构造函数来简单地要求扫描仪使用:

Scanner in = new Scanner(new File(fileName), "ISO-8859-1");

推荐阅读