Написать текстовые файлы без метки порядка байтов (BOM)? - PullRequest
113 голосов
/ 13 марта 2010

Я пытаюсь создать текстовый файл, используя VB.Net с кодировкой UTF8, без спецификации. Кто-нибудь может мне помочь, как это сделать?
Я могу написать файл с кодировкой UTF8, но как удалить из него метку порядка байтов?

edit1: Я пробовал код, подобный этому;

    Dim utf8 As New UTF8Encoding()
    Dim utf8EmitBOM As New UTF8Encoding(True)
    Dim strW As New StreamWriter("c:\temp\bom\1.html", True, utf8EmitBOM)
    strW.Write(utf8EmitBOM.GetPreamble())
    strW.WriteLine("hi there")
    strW.Close()

        Dim strw2 As New StreamWriter("c:\temp\bom\2.html", True, utf8)
        strw2.Write(utf8.GetPreamble())
        strw2.WriteLine("hi there")
        strw2.Close()

1.html создается только в кодировке UTF8, а 2.html создается в формате кодировки ANSI.

Упрощенный подход - http://whatilearnttuday.blogspot.com/2011/10/write-text-files-without-byte-order.html

Ответы [ 9 ]

194 голосов
/ 13 марта 2010

Чтобы опустить метку порядка байтов (BOM), ваш поток должен использовать экземпляр UTF8Encoding, отличный от System.Text.Encoding.UTF8 (который настроен для создания спецификации). ). Есть два простых способа сделать это:

1. Явно указав подходящую кодировку:

  1. Вызовите конструктор UTF8Encoding с False для параметра encoderShouldEmitUTF8Identifier.

  2. Передать экземпляр UTF8Encoding в конструктор потока.

' VB.NET:
Dim utf8WithoutBom As New System.Text.UTF8Encoding(False)
Using sink As New StreamWriter("Foobar.txt", False, utf8WithoutBom)
    sink.WriteLine("...")
End Using
// C#:
var utf8WithoutBom = new System.Text.UTF8Encoding(false);
using (var sink = new StreamWriter("Foobar.txt", false, utf8WithoutBom))
{
    sink.WriteLine("...");
}

2. Использование кодировки по умолчанию:

Если вы вообще не предоставляете конструктор Encoding для StreamWriter, StreamWriter по умолчанию будет использовать кодировку UTF8 без спецификации, поэтому следующее также должно работать:

' VB.NET:
Using sink As New StreamWriter("Foobar.txt")
    sink.WriteLine("...")
End Using
// C#:
using (var sink = new StreamWriter("Foobar.txt"))
{
    sink.WriteLine("...");
}

Наконец, обратите внимание, что исключение спецификации допустимо только для UTF-8, но не для UTF-16.

28 голосов
/ 07 мая 2010

Попробуйте это:

Encoding outputEnc = new UTF8Encoding(false); // create encoding with no BOM
TextWriter file = new StreamWriter(filePath, false, outputEnc); // open file with encoding
// write data here
file.Close(); // save and close it
6 голосов
/ 14 октября 2014

Просто используйте метод WriteAllText из System.IO.File.

Пожалуйста, проверьте образец из File.WriteAllText .

Этот метод использует кодировку UTF-8 без метки порядка байтов (BOM), поэтому использование метода GetPreamble вернет пустой байтовый массив. Если это необходимо включить идентификатор UTF-8, такой как метка порядка байтов, в начало файла, используйте WriteAllText (String, String, Кодировка) перегрузка метода с кодировкой UTF8.

4 голосов
/ 23 июня 2015

Если вы не укажете Encoding при создании нового StreamWriter, по умолчанию Encoding используется объект UTF-8 No BOM, который создается с помощью new UTF8Encoding(false, true).

Таким образом, чтобы создать текстовый файл без спецификации, используйте конструкторы, которые не требуют предоставления кодировки:

new StreamWriter(Stream)
new StreamWriter(String)
new StreamWriter(String, Boolean)
4 голосов
/ 14 апреля 2011

Интересное замечание по этому поводу: как ни странно, статический метод CreateText () класса System.IO.File создает файлы UTF-8 без BOM.

В общем, это источник ошибок, но в вашем случае это мог бы быть самый простой обходной путь:)

3 голосов
/ 27 ноября 2013

Я думаю, что Роман Никитин прав. Значение аргумента конструктора перевернуто. Ложь означает, что нет спецификации, а истина означает, что для спецификации.

Вы получаете кодировку ANSI, поскольку файл без спецификации, не содержащий не ANSI-символов, в точности совпадает с файлом ANSI. Попробуйте некоторые специальные символы в строке «Привет!», И вы увидите изменение кодировки ANSI на без-BOM.

1 голос
/ 24 марта 2016

Кодировка XML UTF-8 без спецификации
Нам необходимо отправить данные XML в EPA, а для их приложения, которое принимает наши данные, требуется UTF-8 без спецификации. О да, обычный UTF-8 должен быть приемлем для всех, но не для EPA. Ответ на это в приведенных выше комментариях. Спасибо Роман Никитин .

Вот фрагмент кода C # для кодировки XML:

    Encoding utf8noBOM = new UTF8Encoding(false);  
    XmlWriterSettings settings = new XmlWriterSettings();  
    settings.Encoding = utf8noBOM;  
        …  
    using (XmlWriter xw = XmlWriter.Create(filePath, settings))  
    {  
        xDoc.WriteTo(xw);  
        xw.Flush();  
    }    

Чтобы увидеть, удаляет ли это три ведущих символа из выходного файла, это может ввести в заблуждение. Например, если вы используете Notepad ++ (www.notepad-plus-plus.org), он сообщит «Кодировать в ANSI». Я предполагаю, что большинство текстовых редакторов рассчитывают на символы спецификации, чтобы определить, является ли это UTF-8. Это можно четко увидеть с помощью бинарного инструмента, такого как WinHex (www.winhex.com). Так как я искал разницу до и после, я использовал приложение Microsoft WinDiff .

0 голосов
/ 22 декабря 2011
Dim sWriter As IO.StreamWriter = New IO.StreamWriter(shareworklist & "\" & getfilename() & ".txt", False, Encoding.Default)

Дает вам результаты, как вы хотите (я думаю).

0 голосов
/ 13 марта 2010

Возможно, ваш входной текст содержит метку порядка байтов. В этом случае вы должны удалить его, прежде чем писать.

...