文章目录
- 1. 现象
- 2. 原因
- 3. BOM
- 3.1 什么是BOM?
- 3.2 BOM的作用
- 3.3 特殊性
- 4. 如何解决乱码?
- 4.1 手动设置格式
- 4.2 自动设置格式
- 4.2.1 Python如何设置:
- 4.2.2 java如何设置
1. 现象
在使用了UTF-8格式编码之后,CSV文件在Excel中打开还是乱码。
2. 原因
win系统在打开CSV文件时,会判断并选择CSV文件的编码格式。
win默认是需要使用带BOM的UTF-8编码,才能打开不乱码。读不到BOM的格式码,会认为是ANSI格式,进而造成csv中的中文乱码。
3. BOM
3.1 什么是BOM?
BOM(Byte Order Mark,字节顺序标记) 是位于文件开头的特殊标记,用于标识文本文件的编码方式和字节顺序(仅对多字节编码如UTF-16/UTF-32有意义)。
3.2 BOM的作用
- 标识编码格式:帮助程序快速识别文件是UTF-8、UTF-16还是UTF-32编码。
- 解决乱码问题:避免程序误判编码(如将UTF-8误认为ANSI/GBK)。
- 字节顺序标记:仅对UTF-16/UTF-32有效(大端序或小端序),UTF-8的字节顺序固定,无需标记顺序
3.3 特殊性
- 非必需但广泛兼容:
UTF-8本身不需要BOM(因字节顺序固定),但Windows系统(如记事本)依赖BOM识别UTF-8文件,无BOM可能被误判为ANSI。 - 现代趋势:
Web开发、代码文件(如JSON、Python)通常禁用BOM,因部分解析器会报错。
4. 如何解决乱码?
4.1 手动设置格式
win系统下将csv文件选择记事本打开,然后另存为,选择格式为“带BOM的UTF-8”,保存完再打开,中文就可以正常显示了。
4.2 自动设置格式
4.2.1 Python如何设置:
写文件
content = "你好"
with open("file.txt", "w", encoding="utf-8-sig") as f: # 'sig'表示BOM
f.write(content)
读文件:
with open("file.txt", "r", encoding="utf-8-sig") as f: # 自动跳过BOM
content = f.read()
4.2.2 java如何设置
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import java.io.*;
public class CsvWithBomCommons {
public static void main(String[] args) throws IOException {
File file = new File("output_with_bom.csv");
// 1. 创建文件输出流并写入BOM
try (OutputStream os = new FileOutputStream(file);
OutputStreamWriter writer = new OutputStreamWriter(os, "UTF-8")) {
// 2. 写入BOM头
os.write(0xEF);
os.write(0xBB);
os.write(0xBF);
// 3. 使用CSVPrinter写入数据 CSVPrinter printer = new CSVPrinter(writer, CSVFormat.DEFAULT);
printer.printRecord("姓名", "年龄");
printer.printRecord("张三", 25);
printer.printRecord("李四", 30);
}
}
}