У меня есть HTTPHandler, который читает набор файлов CSS и объединяет их, а затем GZip-архивирует их. Однако некоторые файлы CSS содержат метку порядка байтов (из-за ошибки в автоматическом слиянии TFS 2005), а в FireFox спецификация считывается как часть фактического содержимого, поэтому это портит имена моих классов и т. д. Как я могу удалить из символов спецификации? Есть ли простой способ сделать это, не просматривая вручную массив байтов в поисках «ï» ¿»?
FWIW, вы можете открывать файлы в Блокнот ++ и сохранять их без отметки порядка байтов. Это то, что мне пришлось делать в этот вопрос.
Я написал следующий пост после того, как столкнулся с этой проблемой. По сути, вместо чтения необработанных байтов содержимого файла с помощью класса BinaryReader я использую класс StreamReader со специальным конструктором, который автоматически удаляет знак отметки порядка байтов из текстовых данных, которые я пытаюсь получить.





Расширяемся на Комментарий Джона сэмплом.
var name = GetFileName();
var bytes = System.IO.File.ReadAllBytes(name);
System.IO.File.WriteAllBytes(name, bytes.Skip(3).ToArray());
Цитата OP: Однако некоторые файлы CSS содержат метку порядка байтов.. .. ** некоторые ** .. поэтому приведенный выше код не проверяет наличие спецификации, прежде чем пропустить ее ...
Другой способ, предполагающий UTF-8 в ASCII.
File.WriteAllText(filename, File.ReadAllText(filename, Encoding.UTF8), Encoding.ASCII);
var text = File.ReadAllText(args.SourceFileName);
var streamWriter = new StreamWriter(args.DestFileName, args.Append, new UTF8Encoding(false));
streamWriter.Write(text);
streamWriter.Close();
Глядя на этот код, в идеале он должен работать. Но я удивлен, что он сохраняет файл в формате ANSI.
new UTF8Encoding(false) параметр указывает, добавлять ли спецификацию или нет.
Расширение примера 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);
}
}
}
Мне понадобился этот фрагмент кода C# после того, как я обнаружил, что спецификация UTF-8 повреждает файл, когда вы пытаетесь выполнить базовый файл загрузки PHP.
Для файла большего размера используйте следующий код; память эффективна!
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();
Появляется ли спецификация в самом тексте или только в самом начале? Я был бы удивлен, увидев это где-нибудь, кроме начала данных - в этом случае простое игнорирование первых 3 байтов (при условии UTF-8) должно помочь.