bom - fancyfsz/FancyWiki GitHub Wiki
BOM(Byte Order Mark)头是一种特殊的字节序标记,通常用于在Unicode文本文件的开头表示字节序(即字节的排列顺序),以帮助解析器正确地识别文本的编码方式。Unicode字符可以使用不同的字节序表示,主要有两种:大端序(Big Endian)和小端序(Little Endian)。
在Unicode编码中,一个字符可能由多个字节组成,字节的排列顺序可以影响字符的解释。因此,为了确保解析文本时能够正确地识别字节序,一些Unicode编码的文件在文件开头插入了BOM头。
BOM头在不同的编码中有不同的表示方式:
UTF-8编码的BOM为3个字节:0xEF
, 0xBB
, 0xBF
UTF-16编码的BOM可以有两种形式:
大端序:0xFE
, 0xFF
小端序:0xFF
, 0xFE
BOM头的作用包括:
- 标识编码方式: BOM头可以帮助解析器识别文件的编码方式,从而正确地解释文件中的字符。
- 字节序识别: 对于UTF-16编码,BOM头可以标识字符的字节序,以便解析器正确地读取字符。
- 避免混淆: 一些文本编辑器和处理工具可能会根据文件的BOM头来判断编码方式,从而避免解析错误。
需要注意的是,并不是所有的Unicode文本文件都需要BOM头。一些文件格式和应用程序可能不支持或不需要BOM头,因此在使用BOM头时需要根据具体情况进行考虑。
以下为去掉所有c#脚本的bom头的bash脚本示例:
files=$(find . -name "*.cs")
for file in "$files"; do
# 找到所有bom并原地替换成空串
sed -i "" 's/\xef\xbb\xbf//g' $file
# 检测含bom头的脚本并打印出来
# (head -c3 $file | LC_ALL=C grep -q $'\xef\xbb\xbf';)&& echo "$file"
done
含BOM头的Lua文件在加载时会失败,一个典型的报错如:
unexpected symbol near '<\239>'
我们可以写一个unity工具来批量处理它们:
using UnityEditor;
using UnityEngine;
using System.IO;
public class RemoveBomWindow : EditorWindow
{
private string inputFolderPath = "Assets"; // 默认为Assets文件夹
private string fileExtension = ".lua.txt"; // 要处理的文件后缀
[MenuItem("Custom/Remove BOM")]
public static void ShowWindow()
{
EditorWindow.GetWindow(typeof(RemoveBomWindow));
}
private void OnGUI()
{
GUILayout.Label("Remove BOM from Files", EditorStyles.boldLabel);
inputFolderPath = EditorGUILayout.TextField("Input Folder Path", inputFolderPath);
fileExtension = EditorGUILayout.TextField("File Extension", fileExtension);
if (GUILayout.Button("Process Files"))
{
ProcessFiles();
}
}
private void ProcessFiles()
{
string[] files = Directory.GetFiles(inputFolderPath, "*" + fileExtension, SearchOption.AllDirectories);
foreach (string file in files)
{
RemoveBOMFromFile(file);
}
AssetDatabase.Refresh();
Debug.Log("BOM头已从所有" + fileExtension + "文件中移除。");
}
private void RemoveBOMFromFile(string filePath)
{
if (File.Exists(filePath))
{
byte[] fileData = File.ReadAllBytes(filePath);
if (fileData.Length >= 3 &&
fileData[0] == 0xEF && fileData[1] == 0xBB && fileData[2] == 0xBF)
{
byte[] newData = new byte[fileData.Length - 3];
System.Array.Copy(fileData, 3, newData, 0, newData.Length);
File.WriteAllBytes(filePath, newData);
Debug.Log("BOM头已经从文件 " + filePath + " 移除。");
}
}
}
}