UTF-8编码不得不说的事情
一贯都喜欢用UTF-8作为系统的编码方式。但是项目中做了一个上传的操作,直接将xml字符串存库。
流读取的时候用的是utf-8编码,上传的文件也是utf-8编码,怎么上传后就乱码了?乱的也不是很离谱,就
在文件的头部,多了一个?字符。可是上传之前的日志输出:没有任何问题。“?”这个字符是从哪里来的。
百度一番,原来utf-8还有 带不带BOM 之分。
BOM: Byte Order Mark
UTF-8 BOM又叫UTF-8 签名,其实UTF-8 的BOM对UFT-8没有作用,是为了支援UTF-16,UTF-32才加上的BOM,BOM签名的意思就是告诉编辑器当前文件采用何种编码,
方便编辑器识别,但是BOM虽然在编辑器中不显示,但是会产生输出。
如果通过java写的UTF-8文件,使用Java可以正确的读,但是如果用记事本将相同的内容使用UTF-8格式保存,则在使用程序读取是会从文件中多读出一个不可见字符。
public static void main(String[] args) throws IOException { File f = new File("C:/utf.txt"); FileInputStream in = new FileInputStream(f); // 指定读取文件时以UTF-8的格式读取 BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8")); String line = br.readLine(); while (line != null) { byte[] allbytes = line.getBytes("UTF-8"); for (int i=0; i < allbytes.length; i++) { int tmp = allbytes[i]; String hexString = Integer.toHexString(tmp); // 1个byte变成16进制的,只需要2位就可以表示了,取后面两位,去掉前面的符号填充 hexString = hexString.substring(hexString.length() -2); System.out.print(hexString.toUpperCase()); System.out.print(" "); } System.out.println(line); line = br.readLine(); } }
/** * 读取流中前面的字符,看是否有bom,如果有bom,将bom头先读掉丢弃 * * @param in * @return * @throws IOException */ public static InputStream trimBOM(InputStream in) throws IOException { PushbackInputStream testin = new PushbackInputStream(in); int ch = testin.read(); if (ch != 0xEF) { testin.unread(ch); } else if ((ch = testin.read()) != 0xBB) { testin.unread(ch); testin.unread(0xef); } else if ((ch = testin.read()) != 0xBF) { throw new IOException("错误的UTF-8格式文件"); } else { // 不需要做,这里是bom头被读完了 // // System.out.println("still exist bom"); } return testin; }编辑器的问题: