Java处理UTF-8文件的BOM头部
BOM——Byte Order Mark,就是字节序标记。
基本概念
- 在
UCS 编码
中有一个叫做”ZERO WIDTH NO-BREAK SPACE
“的字符,它的编码是FEFF
。而FFFE
在UCS
中是不存在的字符,所以不应该出现在实际传输中。 - UCS规范建议我们在传输字节流前,先传输 字符”
ZERO WIDTH NO-BREAK SPACE
“。 - 如果接收者收到
FEFF
,就表明这个字节流是大字节序的;如果收到FFFE
,就表明这个字节流是小字节序的。因此字符”ZERO WIDTH NO-BREAK SPACE
“又被称作BOM
。
UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符”ZERO WIDTH NO-BREAK SPACE
“的UTF-8编码
是EF BB BF
。所以如果接收者收到以EF BB BF
开头的字节流,就知道这是UTF-8编码
了。
这个BOM头部对于UTF-8来说不是必须的,并且我建议最好不用有这个头部,以避免可能的兼容性问题。
下面就来看看怎么用java来处理UTF-8的BOM头部
增加BOM到UTF-8文件
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class AddBomToUtf8File {
public static void main(String[] args) throws IOException {
Path path = Paths.get("/home/file.txt");
writeBomFile(path, "billy");
}
private static void writeBomFile(Path path, String content) {
// Java 8 default UTF-8
try (BufferedWriter bw = Files.newBufferedWriter(path)) {
bw.write("\ufeff");
bw.write(content);
bw.newLine();
bw.write(content);
} catch (IOException e) {
e.printStackTrace();
}
}
}
在Java 8 之前可以用下面的方法:
new OutputStreamWriter(
new FileOutputStream(path.toFile())
, StandardCharsets.UTF_8))) {
bw.write("\ufeff");
bw.write(content);
bw.newLine();
bw.write(content);
} catch (IOException e) {
e.printStackTrace();
}
}
或者可以用 PrintWriter 和OutputStreamWriter
try (PrintWriter pw = new PrintWriter(
new OutputStreamWriter(
new FileOutputStream(path.toFile(