编码检测方法不起作用

时间:2013-03-08 14:49:02

标签: java character-encoding decoding

我需要检查编码类型的文件。如果是readeble则返回true 根据这个SO answer我在Java代码中转换了这个逻辑。但它不起作用。确切地说,这部分代码:

if ((buffer[0] & 0xF8) == 0xF0) {
        if (((buffer[1] & 0xC0) == 0x80)
            && ((buffer[2] == 0x80) && ((buffer[3] == 0x80))))
            return true;
    } else if ((buffer[0] & 0xF0) == 0xE0) {
        if (((buffer[1] & 0xC0) == 0x80) && ((buffer[2] & 0xC0) == 0x80))
            return true;
    } else if ((buffer[0] & 0xE0) == 0xC0) {
        if (((buffer[1] & 0xC0) == 0x80))
            return true;
    } return false;

此时无法正确检查,此时正在检查100%UTF-8代码! =>结果为return false

所有代码:

class EncodindsCheck implements Checker {
    private static final int UTF8_HEADER_SIZE = 8;

    @Override
    public boolean check(File currentFile) {
        return isUTF8(currentFile);
    }

    public static boolean isUTF8(File file) {
        // validate input
        if (null == file) {
            throw new IllegalArgumentException("input file can't be null");
        }
        if (file.isDirectory()) {
            throw new IllegalArgumentException(
                    "input file refers to a directory");
        }

        // read input file
        byte[] buffer;
        try {
            buffer = readUTFHeaderBytes(file);
        } catch (IOException e) {
            throw new IllegalArgumentException(
                    "Can't read input file, error = " + e.getLocalizedMessage());
        }

        if ((buffer[0] & 0xF8) == 0xF0) {
            if (((buffer[1] & 0xC0) == 0x80)
                && ((buffer[2] == 0x80) && ((buffer[3] == 0x80))))
                return true;
        } else if ((buffer[0] & 0xF0) == 0xE0) {
            if (((buffer[1] & 0xC0) == 0x80) && ((buffer[2] & 0xC0) == 0x80))
                return true;
        } else if ((buffer[0] & 0xE0) == 0xC0) {
            if (((buffer[1] & 0xC0) == 0x80))
                return true;
        }

        return false;
    }

    private static byte[] readUTFHeaderBytes(File input) throws IOException {
        byte[] buffer = new byte[UTF8_HEADER_SIZE];
        // read data
        FileInputStream fis = new FileInputStream(input);
        fis.read(buffer);
        fis.close();
        return buffer;
    }
}

问题:

  • 为什么这项检查不起作用?
  • 如何以这种方式解决此检查检测(作为UTF-8字符序列)?
  • 如何查看其他字符集( UTF-16等)?

1 个答案:

答案 0 :(得分:2)

UTF-8中的代码点长度可以是1,2,3或4个字节。

如果所有代码点都在U + 0000到U + 007F的范围内,则isUTF8将返回false。在这种情况下,该文件对大量编码有效(UTF-8,ASCII,ANSI编码等)

您的UTF-8检查确信第一个代码点高于U + 007F。

我建议你看看a more comprehensive encoding detection API,至少作为一个例子。


请注意fis.read(buffer);不能保证填充数组;类型契约要求您检查读取的字节数的返回值。