【问题标题】:Identifying and matching non ascii characters in files识别和匹配文件中的非 ascii 字符
【发布时间】:2015-06-06 17:10:35
【问题描述】:

我正在尝试读取一个分隔文件并解析其内容。与 CSV 不同,分隔符、字符串限定符等不是 ASCII 即。分别为 U0014 和 U00FE。但是,我无法检测到字符串限定符字符 (FE) 。这是因为角色的值大于 128 还是其他原因?

这是一个说明核心问题的简单程序。我怎样才能使这项工作?这是一个非常小的测试文件的链接。 https://www.dropbox.com/s/1cilircwc3pq78c/nonascii.dat?dl=0

谢谢

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Reader;

public class CharMatch {
    public static void main(String[] args)
        throws Exception {
    final String pathname = "/home/vinayb/Downloads/nonascii.dat";
    final File file = new File(pathname);
    final String encoding = "UTF-8";
    final PrintStream out = new PrintStream(System.out, true, encoding);
    final Reader r = new BufferedReader(new InputStreamReader(
            new FileInputStream(file), encoding));

    final LineIterator it = FileUtils.lineIterator(file, encoding);
    try {
        //read a line
        final String line = it.nextLine();
        final char[] chars = line.toCharArray();
        for (char c : chars) {
            out.println(c + " , with decimal value: " + Character.getNumericValue(c) + " and hexa value: " + Integer.toHexString(Character.getNumericValue(c)));
        }

        out.println("------------------------------------");
        final String expectedDelimiter = fromUnicode("0014");
        final String expectedStringQualifier = fromUnicode("00FE");
        out.println("##### expected delimiter:" + expectedDelimiter);

        out.println("##### expected string qualifier:" + expectedStringQualifier);
        String[] items = line.split(expectedDelimiter);
        out.println("#### " + items.length + " " + items[0]);

        if (line.contains(expectedDelimiter)) {
            out.println("Found delimiter"); ////=======> can match this
        }

        if (line.contains(expectedStringQualifier)) {
            out.println("Found string qualifier"); //=======> can't match this
        }
    } finally {
        LineIterator.closeQuietly(it);
    }
}

private static String fromUnicode(String codePoint) {
    return "" + (char) Integer.parseInt(codePoint, 16);
}

}

【问题讨论】:

  • “字符串限定符”?那应该是什么?
  • 这是一个用于限定字符串的字符。常用的分隔符是 "。例如,在 csv 中,我们将使用分隔符 "John Doe", "123, Main Street" 。在这种情况下,分隔符是 00FE 。请参阅此链接了解它的样子 en.wikipedia.org/wiki/ISO/IEC_8859-1

标签: java encoding utf non-ascii-characters


【解决方案1】:

看看here。 00 FE 可能是 UTF-16 的正确代码,但在 UTF-8 中它是 C3 BE。这也可以解释为什么它不是有效的 UTF-8。

【讨论】:

    【解决方案2】:

    您的文件不是有效的 UTF-8:

    $ iconv -f utf-8 *dat >/dev/null; echo $?
    iconv: illegal input sequence at position 0
    1
    

    但它可以被“读取”为 ISO-8859-1:

    $ iconv -f iso-8859-1 *dat >/dev/null; echo $?
    0
    

    只需将编码更改为该编码即可;但是2015年这样的文件格式就比较奇怪了。你真正应该做的是要求这些文件的来源与时俱进;)

    请注意,由于第一个字节序列无效,默认情况下 Java 会将其替换为U+FFFD;并且它将对无法转换为chars 的每个字节序列执行此操作。即使在这种情况下,为了让 Java 抛出异常,您需要实例化 CharsetDecoder(来自 Charset 实例)并指定您想要 .onMalformedInput(CodingErrorAction.REPORT)(默认为 CodingErrorAction.REPLACE)。

    【讨论】:

    • 我使用了 ISO-8859-1 格式并且允许我读取文件
    猜你喜欢
    • 2013-09-22
    • 2022-01-23
    • 1970-01-01
    • 2019-02-13
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    相关资源
    最近更新 更多