Предотвратить File.WriteAllText для записи двойной метки порядка байтов (BOM)? - PullRequest
0 голосов
/ 30 мая 2018

В следующем примере, если (строка) текст начинается с спецификации, File.writeAllText () добавит еще одну , записав две спецификации .

Я хочу написать текст два раза:

  1. Без спецификации вообще
  2. С одной спецификацией (если применимо к кодировке)

Чтоканонический способ добиться этого?

HttpWebResponse response = ...
Byte[] byte = ... // bytes from response possibly including BOM 

var encoding = Encoding.GetEncoding(
                    response.get_CharacterSet(),
                    new EncoderExceptionFallback(),
                    new DecoderExceptionFallback()
               );
string text = encoding.GetString(bytes); // will preserve BOM if any
System.IO.File.WriteAllText(fileName, text, encoding);

1 Ответ

0 голосов
/ 30 мая 2018

Вы декодируете, а затем перекодируете файл ... Это совершенно бесполезно.

Внутри класса Encoding есть метод GetPreamble(), который возвращает преамбулу (называемую спецификацией для кодировок utf- *).), в byte[].Затем мы можем проверить, имеет ли полученный массив bytes этот префикс или нет.Затем, основываясь на этой информации, мы можем написать две версии файла, добавив или удалив префикс при необходимости.

var encoding = Encoding.GetEncoding(response.CharacterSet, new EncoderExceptionFallback(), new DecoderExceptionFallback());

// This will throw if the file is wrongly encoded
encoding.GetCharCount(bytes);

byte[] preamble = encoding.GetPreamble();

bool hasPreamble = bytes.Take(preamble.Length).SequenceEqual(preamble);

if (hasPreamble)
{
    File.WriteAllBytes("WithPreambleFile.txt", bytes);

    using (var fs = File.OpenWrite("WithoutPreamble.txt"))
    {
        fs.Write(bytes, preamble.Length, bytes.Length - preamble.Length);
    }
}
else
{
    File.WriteAllBytes("WithoutPreambleFile.txt", bytes);

    using (var fs = File.OpenWrite("WithPreamble.txt"))
    {
        fs.Write(preamble, 0, preamble.Length);
        fs.Write(bytes, 0, bytes.Length);
    }
}
...