java.util.Scanner 中的错误

A bug in java.util.Scanner

java.util.Scanner 无法处理文件内容中的不间断 space,这很奇怪。

这是输入文本,将其放入名为 asdf.txt:

的文件中
lines lines lines
asdf jkl
lines lines lines

asdfjkl之间是一个不间断的space。具体来说:

echo "asdf jkl" | od -c
0000000   a   s   d   f 302 240   j   k   l  \n
0000012

你可以copy/paste在这里看到它:http://www.fontspace.com/unicode/analyzer/

违规字符也被称为:302 240U+00A0   %C2%A0

代码:

import java.util.*;
import java.io.*;
public class Main{
    public static void main(String args[]){
        Scanner r = null;
        try{
            File f = new File("/home2/ericlesc/testfile/asdf.txt");
            r = new Scanner(f);
            while(r.hasNextLine()){
                String line = r.nextLine();
                System.out.println("line is: " + line);
            }   
            System.out.println("done");
        }   
        catch(Exception e){ 
            e.printStackTrace();
        }   
    }   
}

java.util.Scanner 吐了这个内容。令人惊讶的是,它不会抛出异常 "can't process this character"。它不会停在有问题的行上,扫描仪会在有问题的字符之前吐出大约 30 个字符。

也许有关于如何使用 java.util.Scanner 阅读非中断 space 而不会呕吐的已知文档?

为什么 java.util.Scanner 无法处理非中断 space?我怎样才能让它正常处理?

除非您另有说明,否则扫描程序会采用系统的默认字符集。我不确定其他操作系统,但在 Windows 上,出于兼容性原因,这是 ISO 8859 字符集之一。

幸运的是,您可以通过使用 this one.

等 2 个参数构造函数之一来告诉 Scanner 您希望它使用什么 CharSet

在 powerlord 的帮助下,我能够使用此代码生成所需的输出:

import java.util.*;
import java.io.*;
public class Main{
    public static void main(String args[]){
        Scanner r = null;
        try{
            File f = new File("/home2/ericlesc/testfile/asdf.txt");
            r = new Scanner(f, "ISO-8859-1");
            while(r.hasNextLine()){
                String line = r.nextLine();
                System.out.println("line is: " + line);
            }   
            System.out.println("done");
        }   
        catch(Exception e){ 
            e.printStackTrace();
        }   
    }   
}

程序打印:

javac Main.java && java Main

line is: lines lines lines
line is: asdf jkl
line is: lines lines lines

您必须指定用于对字符进行编码的相同字符集,否则扫描器在遇到它不理解的字符时会出现未定义的行为。