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 + " 移除。");
            }
        }
    }
}
⚠️ **GitHub.com Fallback** ⚠️