最近一段時間作東西,總是因為要處理可能不通字符集的文件而煩心,雖然遭到一個程序庫,好象是模仿Mozilla的一個C庫使用java實現(xiàn)的,但是普通的情況下使用這個庫是不是太大了點.于是將GBK作為默認編碼,主要判斷utf-8,我實現(xiàn)了一個程序,在Windows下邊如果使用記事本保存的TXT文件帶有BOM當(dāng)然很方便,但是如果沒有BOM的話,就只有通過文件中的字符的編碼來判斷了,經(jīng)過幾次簡單的實驗,發(fā)現(xiàn)尚且可用。JAVA源碼如下,懇請指正:
static String get_charset(File file) {
String charset = "GBK";
byte [] first3Bytes = new byte[3];
try {
boolean checked = false;
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
bis.mark(0);
int read = bis.read(first3Bytes, 0, 3);
if (read == -1) return charset;
if (first3Bytes[0] == (byte)0xFF && first3Bytes[1] == (byte)0xFE) {
charset = "UTF-16LE";
checked = true;
}
else if(first3Bytes[0] == (byte)0xFE && first3Bytes[1] == (byte)0xFF) {
charset = "UTF-16BE";
checked = true;
}
else if(first3Bytes[0] == (byte)0xEF && first3Bytes[1] == (byte)0xBB && first3Bytes[2] == (byte)0xBF) {
charset = "UTF-8";
checked = true;
}
bis.reset();
if (!checked) {
int len = 0;
int loc = 0;
while ((read = bis.read()) != -1) {
loc ++;
if (read >= 0xF0)
break;
if (0x80<=read && read <= 0xBF) //單獨出現(xiàn)BF以下的,也算是GBK
break;
if (0xC0<=read && read <= 0xDF) {
read = bis.read();
if (0x80<= read && read <= 0xBF)//雙字節(jié) (0xC0 - 0xDF) (0x80 - 0xBF),也可能在GB編碼內(nèi)
continue;
else
break;
} else if (0xE0 <= read && read <= 0xEF) {//也有可能出錯,但是幾率較小
read = bis.read();
if (0x80<= read && read <= 0xBF) {
read = bis.read();
if (0x80<= read && read <= 0xBF) {
charset = "UTF-8";
break;
} else
break;
} else
break;
}
}
System.out.println(loc + " " + Integer.toHexString(read));
}
bis.close();
} catch (Exception e) {
e.printStackTrace();
}
return charset;
}
static String get_charset(File file) {
String charset = "GBK";
byte [] first3Bytes = new byte[3];
try {
boolean checked = false;
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
bis.mark(0);
int read = bis.read(first3Bytes, 0, 3);
if (read == -1) return charset;
if (first3Bytes[0] == (byte)0xFF && first3Bytes[1] == (byte)0xFE) {
charset = "UTF-16LE";
checked = true;
}
else if(first3Bytes[0] == (byte)0xFE && first3Bytes[1] == (byte)0xFF) {
charset = "UTF-16BE";
checked = true;
}
else if(first3Bytes[0] == (byte)0xEF && first3Bytes[1] == (byte)0xBB && first3Bytes[2] == (byte)0xBF) {
charset = "UTF-8";
checked = true;
}
bis.reset();
if (!checked) {
int len = 0;
int loc = 0;
while ((read = bis.read()) != -1) {
loc ++;
if (read >= 0xF0)
break;
if (0x80<=read && read <= 0xBF) //單獨出現(xiàn)BF以下的,也算是GBK
break;
if (0xC0<=read && read <= 0xDF) {
read = bis.read();
if (0x80<= read && read <= 0xBF)//雙字節(jié) (0xC0 - 0xDF) (0x80 - 0xBF),也可能在GB編碼內(nèi)
continue;
else
break;
} else if (0xE0 <= read && read <= 0xEF) {//也有可能出錯,但是幾率較小
read = bis.read();
if (0x80<= read && read <= 0xBF) {
read = bis.read();
if (0x80<= read && read <= 0xBF) {
charset = "UTF-8";
break;
} else
break;
} else
break;
}
}
System.out.println(loc + " " + Integer.toHexString(read));
}
bis.close();
} catch (Exception e) {
e.printStackTrace();
}
return charset;
}