感谢大佬 jiangqin115 提供的C++版本,我将他翻译成了JAVA版本
C++原文链接:https://blog.csdn.net/jiangqin115/article/details/42684017
原文版权声明:遵循 CC 4.0 BY-SA 版权协议
从原文可见,他的代码从二进制层面判断了文件是否遵循UTF-8规则
比如这段
1字节:0xxxxxxx
2字节:110xxxxx 10xxxxxx
3字节:1110xxxx 10xxxxxx 10xxxxxx
4字节:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
建议大家可以到原帖学习一番。
在这里我将原文的C++翻译成了JAVA
核心的判断条件没有改变,只是为了 java 的特性和局限性做了适配
实测这种判断方式非常有效,而且该种写法的优点在于,可以适配文本无BOM头的情况
这里直接贴出方法好了:
/**
* 判断文件内容是否为 UTF-8 编码
* 翻译自C++版本 @see <a href="https://blog.csdn.net/jiangqin115/article/details/42684017">cpp原文</a>
* @author Piao
*/
public boolean IsUTF8(FileInputStream fis) {
//请注意FileInputStream是流,是不能复用的!
try {
while (true) {
int curr = fis.read();
System.out.println(curr);
if (curr == -1) {
return true;
}
if (curr < 0x80) {// (10000000): 值小于0x80的为ASCII字符
} else if (curr < (0xC0)) { // (11000000): 值介于0x80与0xC0之间的为无效UTF-8字符
return false;
} else if (curr < (0xE0)) { // (11100000): 此范围内为2字节UTF-8字符
if ((fis.read() & (0xC0)) != 0x80) {
return false;
}
} else if (curr < (0xF0)) { // (11110000): 此范围内为3字节UTF-8字符
if ((fis.read() & (0xC0)) != 0x80 || (fis.read() & (0xC0)) != 0x80) {
return false;
}
} else {
return false;
}
}
} catch (IOException e) {
e.printStackTrace();
return true;
}
}