4

我有一个包含 1000 行的文本文件,格式如下:

19 x 75 Bullnose Architrave/Skirting £1.02 

我正在编写一个逐行读取文件的方法 - 这工作正常。

然后,我想使用“£”作为分隔符拆分每个字符串,并将其写入ArrayList<String>以下格式:

19 x 75 Bullnose Architrave/Skirting, Metre, 1.02

这就是我处理它的方式(productListArrayList在 try 块之外声明/实例化的 , ):

try{
    br = new BufferedReader(new FileReader(aFile));
    String inputLine = br.readLine();
    String delim = "£";

    while (inputLine != null){
        String[]halved = inputLine.split(delim, 2);
        String lineOut = halved[0] + ", Metre, " + halved[1];//Array out of bounds
        productList.add(lineOut);

        inputLine = br.readLine();
    }
}

字符串没有分裂,我不断得到一个ArrayIndexOutOfBoundsException. 我对正则表达式不是很熟悉。我也尝试过使用旧的StringTokenizer但得到相同的结果。

£作为 delim有问题还是其他问题?我确实想知道这是否与第二个令牌没有被读取为String?

任何想法都会有所帮助。

4

3 回答 3

6

以下是一些可能的原因:

  • 文件的编码与您用来读取它的编码不匹配,并且文件中的“磅”字符被“破坏”成其他东西。

  • 该文件和您的源代码使用不同的类似英镑的字符。例如,Unicode 有两个看起来像“磅符号”的代码点——英镑字符 (00A3) 和里拉字符 (2084)……然后是罗马字符 (10192)。

  • 您正在尝试编译 UTF-8 编码的源文件而不告诉编译器它是 UTF-8 编码的。


从您的评论来看,这是一个编码不匹配的问题;即Java 使用的“默认”编码与文件的实际编码不匹配。有两种方法可以解决这个问题:

  • 更改文件的编码以匹配 Java 的默认编码。您似乎已经尝试过但失败了。(这不会是我这样做的方式......)

  • 更改程序以使用特定(非默认)编码打开文件;例如改变

    new FileReader(aFile)
    

    new FileReader(aFile, encoding)
    

    其中encoding是文件的实际字符编码的名称。Java 可以理解的编码名称在此处列出,但我的猜测是它是“ISO-8859-1”(又名 Latin-1)。

于 2012-12-20T10:24:29.403 回答
0

这可能是编码不匹配的情况。要检查这一点,

  • 打印delim.length并确保它是1.
  • 打印inputLine.length并确保它是正确的值 ( 42)。

如果其中之一不是预期值,那么您必须确保在任何地方都使用 UTF-8。

你说delim.length是1,所以这很好。另一方面,如果inputLine.length是 34,这是非常错误的。因为"19 x 75 Bullnose Architrave/Skirting £1.02"如果一切都符合预期,你应该得到 42。如果您的文件是 UTF-8 编码但读取为 ISO-8859-1 或类似文件,您将得到 43。

现在我有点不知所措。要调试它,您可以单独打印字符串的每个字符并检查它们有什么问题。

for (int i = 0; i < inputLine.length; i++)
    System.err.println("debug: " + i + ": " + inputLine.charAt(i) + " (" + inputLine.codePointAt(i) + ")");
于 2012-12-20T10:20:53.937 回答
-1

非常感谢您的所有回复。

在读取中指定编码并将原始文本文件保存为 UTF -8 有效。

然而,经验告诉我,使用“£”或其他可能在不同编码中具有多种表示的字符来分隔文本是一种糟糕的策略。

我决定采取不同的方法:

1) 查找输入字符串中的最后一个空格并将其替换为“xxx”或类似名称。

2) 使用分隔符“xxx”将其拆分。这应该拆分字符串并撕掉“£”。

3) 继续..

于 2012-12-20T23:12:13.073 回答