在项目中有一个功能是从本地上传一个txt文件,按行读取文件内容,并按规定的格式解析文件,并把解析出来的数据存入数据库。并
且文件的格式需要根据文件的内容进行判断。
这个需要主要由两个功能组成,一个是文件上传,一个是读文件。
文件上传使用struts2的文件上传功能,读文件肯定是java.io了。不过这里的重点并不是说明文件上传或者是java的IO,而是如何知道
文件的编码格式。
在开发这个功能的时候,直接把文件按照UTF-8的格式进行导入,这时候发现如果文件是另存为UTF-8时,可以导入,但是如果是其他编
码,就导入失败。这时候就想到能不能获取编码格式,然后直接baidu,按照网友分享的经验,果然可以。下面给出我是如何做到的,一起看
代码。
1、在主方法里面构造输入流,注意参数,需要一个文件编码
String charset = getCharset(file);
fr = new InputStreamReader(new FileInputStream(file), charset);
2、这个方法是判断文件的编码的,发现有些编码,文件内容前面多了几个字节,就根据这几个字节来判断,你自己调试一下看看
private static String getCharset(File fileName) throws IOException {
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(fileName));
byte[] b = new byte[10];
bin.read(b, 0, b.length);
String first = toHex(b);
//这里可以看到各种编码的前几个字符是什么,gbk编码前面没有多余的
String code = null;
if (first.startsWith(“EFBBBF”)) {
code = “UTF-8”;
} else if (first.startsWith(“FEFF00”)) {
code = “UTF-16BE”;
} else if (first.startsWith(“FFFE”)) {
code = “Unicode”;
} else if (first.startsWith(“FFFE”)) {
code = “Unicode”;
} else {
code = “GBK”;
}
return code;
}
//把字节数组转换成字符串
public static String toHex(byte[] byteArray) {
int i;
StringBuffer buf = new StringBuffer(“”);
int len = byteArray.length;
for (int offset = 0; offset < len; offset++) {
i = byteArray[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append(“0”);
buf.append(Integer.toHexString(i));
}
return buf.toString().toUpperCase();
}
3、虽然获取了编码,但是在读UTF-8文件的时候,经过尝试,发现还要去掉第一个字符,文件第一行前面多了一个字符,很像波浪号,但又
不是
if (temp == null) {
if (charset.equalsIgnoreCase(“UTF-8”)) {
str = str.substring(1);
}
}