C# 从文件中删除字节顺序标记。ReadAllBytes(字节[])

C# 从文件中删除字节顺序标记。ReadAllBytes(字节[]),c#,byte-order-mark,C#,Byte Order Mark,我有一个HTTPHandler,它读取一组CSS文件,并将它们组合起来,然后gzip它们。然而,一些CSS文件包含一个字节顺序标记(由于TFS 2005自动合并中的一个错误),并且在FireFox中,BOM作为实际内容的一部分被读取,因此它会弄乱我的类名等。我如何去掉BOM字符?有没有一种简单的方法可以做到这一点,而无需手动通过字节数组查找“ï»”?用示例展开 var name = GetFileName(); var bytes = System.IO.File.ReadAllBytes(na

我有一个HTTPHandler,它读取一组CSS文件,并将它们组合起来,然后gzip它们。然而,一些CSS文件包含一个字节顺序标记(由于TFS 2005自动合并中的一个错误),并且在FireFox中,BOM作为实际内容的一部分被读取,因此它会弄乱我的类名等。我如何去掉BOM字符?有没有一种简单的方法可以做到这一点,而无需手动通过字节数组查找“ï»”?

用示例展开

var name = GetFileName();
var bytes = System.IO.File.ReadAllBytes(name);
System.IO.File.WriteAllBytes(name, bytes.Skip(3).ToArray());

另一种方式,假设UTF-8为ASCII

File.WriteAllText(filename, File.ReadAllText(filename, Encoding.UTF8), Encoding.ASCII);

正在扩展JaredPar示例以在子目录上递归:

using System.Linq;
using System.IO;
namespace BomRemover
{
    /// <summary>
    /// Remove UTF-8 BOM (EF BB BF) of all *.php files in current & sub-directories.
    /// </summary>
    class Program
    {
        private static void removeBoms(string filePattern, string directory)
        {
            foreach (string filename in Directory.GetFiles(directory, file  Pattern))
            {
                var bytes = System.IO.File.ReadAllBytes(filename);
                if(bytes.Length > 2 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF)
                {
                    System.IO.File.WriteAllBytes(filename, bytes.Skip(3).ToArray()); 
                }
            }
            foreach (string subDirectory in Directory.GetDirectories(directory))
            {
                removeBoms(filePattern, subDirectory);
            }
        }
        static void Main(string[] args)
        {
            string filePattern = "*.php";
            string startDirectory = Directory.GetCurrentDirectory();
            removeBoms(filePattern, startDirectory);            
        }       
    }
}
使用System.Linq;
使用System.IO;
命名空间BomRemover
{
/// 
///删除当前和子目录中所有*.php文件的UTF-8 BOM(EF BB BF)。
/// 
班级计划
{
私有静态void removeBoms(字符串文件模式、字符串目录)
{
foreach(Directory.GetFiles(目录,文件模式)中的字符串文件名)
{
var bytes=System.IO.File.ReadAllBytes(文件名);
如果(bytes.Length>2&&bytes[0]==0xEF&&bytes[1]==0xBB&&bytes[2]==0xBF)
{
System.IO.File.writealBytes(文件名,bytes.Skip(3.ToArray());
}
}
foreach(Directory.GetDirectories(Directory))中的字符串子目录
{
removeBoms(文件模式,子目录);
}
}
静态void Main(字符串[]参数)
{
字符串filePattern=“*.php”;
字符串startDirectory=Directory.GetCurrentDirectory();
removeBoms(filePattern,startDirectory);
}       
}
}

当您尝试执行基本PHP下载文件时,发现UTF-8 BOM会损坏文件,我需要这段C#代码;内存效率高

StreamReader sr = new StreamReader(path: @"<Input_file_full_path_with_byte_order_mark>", 
                    detectEncodingFromByteOrderMarks: true);

StreamWriter sw = new StreamWriter(path: @"<Output_file_without_byte_order_mark>", 
                    append: false, 
                    encoding: new UnicodeEncoding(bigEndian: false, byteOrderMark: false));

var lineNumber = 0;
while (!sr.EndOfStream)
{
    sw.WriteLine(sr.ReadLine());
    lineNumber += 1;
    if (lineNumber % 100000 == 0)
        Console.Write("\rLine# " + lineNumber.ToString("000000000000"));
}

sw.Flush();
sw.Close();
StreamReader sr=新的StreamReader(路径:@“”,
从字节顺序标记中检测到编码:true);
StreamWriter sw=新StreamWriter(路径:@“”,
附加:false,
编码:新的Unicode编码(bigEndian:false,byteOrderMark:false);
var lineNumber=0;
而(!sr.EndOfStream)
{
sw.WriteLine(sr.ReadLine());
行号+=1;
如果(行号%100000==0)
Console.Write(“\rLine#”+lineNumber.ToString(“000000000000”));
}
sw.Flush();
sw.Close();

查看此代码,理想情况下它应该可以工作。但是,我很惊讶它是以ANSI格式保存文件。
new UTF8Encoding(false)
该参数指示是否添加BOM表。BOM表是以实际文本本身显示,还是仅在开始时显示?我会惊讶地看到它出现在数据开头以外的任何地方——在这种情况下,只需忽略前3个字节(假设UTF-8)就可以了。FWIW,您可以在中打开文件并保存它们,而不带字节顺序标记。这是我必须做的。我在遇到这个问题后写了这篇文章。基本上,我没有使用BinaryReader类读取文件内容的原始字节,而是使用StreamReader类和一个特定的构造函数,该构造函数会自动从我试图检索的文本数据中删除字节顺序标记字符。Quote OP:但是,一些CSS文件包含字节顺序标记…**一些**。。所以上面的代码在跳过BOM之前不会检查是否存在BOM。。。
StreamReader sr = new StreamReader(path: @"<Input_file_full_path_with_byte_order_mark>", 
                    detectEncodingFromByteOrderMarks: true);

StreamWriter sw = new StreamWriter(path: @"<Output_file_without_byte_order_mark>", 
                    append: false, 
                    encoding: new UnicodeEncoding(bigEndian: false, byteOrderMark: false));

var lineNumber = 0;
while (!sr.EndOfStream)
{
    sw.WriteLine(sr.ReadLine());
    lineNumber += 1;
    if (lineNumber % 100000 == 0)
        Console.Write("\rLine# " + lineNumber.ToString("000000000000"));
}

sw.Flush();
sw.Close();