Java OutOfMemoryError-来自检测UTF-8编码
此类应检查Java OutOfMemoryError-来自检测UTF-8编码,java,utf-8,character-encoding,detect,Java,Utf 8,Character Encoding,Detect,此类应检查currentFile并检测编码。如果结果为UTF-8则返回true runnig之后的输出是-java.lang.OutOfMemoryError:java堆空间 对于读取数据,此文件需要有JDK 7。readAllBytes(路径) 代码: class EncodingsCheck implements Checker { @Override public boolean check(File currentFile) { return isUTF
currentFile
并检测编码。如果结果为UTF-8则返回true
runnig之后的输出是-java.lang.OutOfMemoryError:java堆空间
对于读取数据,此文件需要有JDK 7。readAllBytes(路径)
代码:
class EncodingsCheck implements Checker {
@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 (0 == (buffer[0] & 0x80)) {
return true; // ASCII subset character, fast path
} else if (0xF0 == (buffer[0] & 0xF8)) { // start of 4-byte sequence
if (buffer[3] >= buffer.length) {
return false;
}
if ((0x80 == (buffer[1] & 0xC0)) && (0x80 == (buffer[2] & 0xC0))
&& (0x80 == (buffer[3] & 0xC0)))
return true;
} else if (0xE0 == (buffer[0] & 0xF0)) { // start of 3-byte sequence
if (buffer[2] >= buffer.length) {
return false;
}
if ((0x80 == (buffer[1] & 0xC0)) && (0x80 == (buffer[2] & 0xC0))) {
return true;
}
} else if (0xC0 == (buffer[0] & 0xE0)) { // start of 2-byte sequence
if (buffer[1] >= buffer.length) {
return false;
}
if (0x80 == (buffer[1] & 0xC0)) {
return true;
}
}
return false;
}
private static byte[] readUTFHeaderBytes(File input) throws IOException {
// read data
Path path = Paths.get(input.getAbsolutePath());
byte[] data = Files.readAllBytes(path);
return data;
}
}
问题:
- 如何解决这个问题李>
- 如何通过这种方式检查UTF-16 (我们需要担心这件事还是这只是无用的麻烦)
- 您不需要读取整个文件
private static byte[] readUTFHeaderBytes(File input) throws IOException {
FileInputStream fileInputStream = new FileInputStream(input);
try{
byte firstBytes[] = new byte[4];
int count = fileInputStream.read(firstBytes);
if(count < 4){
throw new IOException("Empty file");
}
return firstBytes;
} finally {
fileInputStream.close();
}
}
private static byte[]readUTFHeaderBytes(文件输入)引发IOException{
FileInputStream FileInputStream=新的FileInputStream(输入);
试一试{
字节firstBytes[]=新字节[4];
int count=fileInputStream.read(firstBytes);
if(计数<4){
抛出新IOException(“空文件”);
}
返回第一个字节;
}最后{
fileInputStream.close();
}
}
要检测其他UTF编码,请使用给定的模式:
Bytes Encoding Form
00 00 FE FF UTF-32, big-endian
FF FE 00 00 UTF-32, little-endian
FE FF UTF-16, big-endian
FF FE UTF-16, little-endian
EF BB BF UTF-8
字节编码形式
00 FE FF UTF-32,大端
FF FE 00 UTF-32,小端
FE FF UTF-16,大端
FF FE UTF-16,小端
EF BB BF UTF-8
如果只需要文件的前四个字节来检测标题,为什么要将整个文件读入内存?想一想,如果这是一个1GB的文件,会发生什么。@mellamokb如何绕过这个耗费资源的过程?@nazar_art Search for“Java读取文件教程”。找到一个关于
InputStream
s的文件。在这个例子中,你能说说实现检测UTF-16吗?“如果你只需要文件的前四个字节来检测标题,为什么要将整个文件读入内存?想想如果这是一个1GB的文件会发生什么。”-那么,搜索使用InputStream
s的教程。此处描述的方法基于UTF BOM(字节顺序标记)。有些应用程序生成此标头,但有些应用程序不生成此标头。因此,这种方法适用于某些文件,但并不完全通用。文件
和类似应用程序有时做的是读取样本,例如文件的前64 kB,并在其上运行整个解码过程。它比检查BOM更通用,但比加载和解码整个文件使用更少的资源。@MichałKosmulski同意,没有100%的方法知道编码Apache IO Commons提供了一种简单的方法来检测BOM存在时的文件编码:@Smertokogt如果(0==(缓冲区[0]&0x80))如何更改此部分if(0==(缓冲区[0]&0x80)){…return false;}
从UTF-8到UTF-16检测编码?如何确定这个数字(…&0xF8)
和0xF0==
之后?