之前寫過一篇java利用JAXB實(shí)現(xiàn)對(duì)象和xml互轉(zhuǎn)
最近發(fā)現(xiàn)如果xml格式為utf-8-bom格式 而不是utf-8格式的時(shí)候铐炫,jaxb處理會(huì)報(bào)錯(cuò)。
UTF-8 BOM又叫UTF-8 簽名蒜焊,UTF-8不需要BOM來表明字節(jié)順序倒信,但可以用BOM來表明編碼方式。當(dāng)文本程序讀取到以 EF BB BF開頭的字節(jié)流時(shí)泳梆,就知道這是UTF-8編碼了鳖悠。Windows就是使用BOM來標(biāo)記文本文件的編碼方式的。
所以可以了解到Bom是微軟的習(xí)慣优妙,java是沒有直接兼容這種標(biāo)準(zhǔn)乘综,這種標(biāo)準(zhǔn)和普通的utf-8的xml的區(qū)別只是在文件開頭多了三個(gè)字節(jié):EFBBBF
所以我們的處理思路是拿到xml文件之后,讀取前三個(gè)字節(jié)是否是EFBBBF就可以判斷是不是utf-8-bom這種格式套硼,移除掉這三個(gè)字節(jié)就能轉(zhuǎn)換成標(biāo)準(zhǔn)的utf-8,這樣jaxb就可以處理了卡辰。
新建UTF8BomUtil:
package com.ly.mp.project.utils;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.commons.codec.binary.Hex;
public class UTF8BomUtil {
public static boolean isContainBOM(String filePath) throws IOException {
Path path = Paths.get(filePath);
if (Files.notExists(path)) {
throw new IllegalArgumentException("Path: " + path + " does not exists!");
}
boolean result = false;
byte[] bom = new byte[3];
try (InputStream is = new FileInputStream(path.toFile())) {
// read first 3 bytes of a file.
is.read(bom);
// BOM encoded as ef bb bf
String content = new String(Hex.encodeHex(bom));
if ("efbbbf".equalsIgnoreCase(content)) {
result = true;
}
}
return result;
}
public static void main(String[] args) throws IOException {
String utf8BomPath = "D://tmp/utf8bomTest/Application_and_calibration.odx-f";
boolean flag = UTF8BomUtil.isContainBOM(utf8BomPath);
System.out.println(flag);
}
}
上面這個(gè)方法可以識(shí)別utf-8-bom文件,接下來去掉開頭這三個(gè)字節(jié)即可邪意,可以用
org.apache.commons.io.FileUtils;
public static void removeByte(String filePath, int byteSize) throws IOException {
File file = new File(filePath);
byte[] bytes = FileUtils.readFileToByteArray(file);
byte[] bytesNew = new byte[bytes.length - byteSize];
for(long i = 0; i < bytes.length; i++) {
if(i >= byteSize) {
bytesNew[(int) (i-byteSize)] = bytes[(int) i];
}
}
FileUtils.writeByteArrayToFile(file, bytesNew);
}