Написать текстовые файлы без метки порядка байтов (BOM)?

104

Я пытаюсь создать текстовый файл, используя 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

  • 8
    Если вам не нужна спецификация, почему вы пишете GetPreamble ()?
Теги:
encoding
file-handling
byte-order-mark

9 ответов

179
Лучший ответ

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

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

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

  • Передайте экземпляр 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.

  • 0
    Не всегда разумно: например, My.Computer.FileSystem.WriteAllText записывает спецификацию, если кодировка не указана.
  • 0
    My.Computer.FileSystem.WriteAllText является исключением в этом отношении, возможно, предполагая обратную совместимость с VB? File.WriteAllText умолчанию имеет значение UFT8NoBOM.
29

Попробуйте следующее:

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
5

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

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

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

  • 0
    Один из пространства имен My использует BOM
4

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

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

new StreamWriter(Stream)
new StreamWriter(String)
new StreamWriter(String, Boolean)
  • 0
    Что делать, если мне нужно указать, чтобы leaveOpen ?
  • 0
    @binki в этом случае вы не можете использовать кодировку по умолчанию, которую использует StreamWriter . Вам нужно будет указать new UTF8Encoding(false, true) для вашей кодировки, чтобы иметь возможность указывать leaveOpen и не иметь спецификации.
4

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

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

3

Я думаю, что Роман Никитин прав. Значение аргумента конструктора перевернуто. False означает, что нет спецификации и истинных средств с спецификацией.

Вы получаете кодировку ANSI, потому что файл без спецификации, не содержащей символов, отличных от ansi, точно такой же, как файл ANSI. Попробуйте ввести некоторые специальные символы в строку "hi there", и вы увидите изменение кодировки ANSI без спецификации.

1

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

Вот фрагмент кода С# для кодировки 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.

-1
Dim sWriter As IO.StreamWriter = New IO.StreamWriter(shareworklist & "\" & getfilename() & ".txt", False, Encoding.Default)

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

  • 1
    На моем компьютере он создает файлы ANSI
-2

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

  • 1
    Пожалуйста, помогите мне. Как убрать это перед написанием.
  • 0
    @ user180326 разве читатель по умолчанию уже не отфильтровывает это для вас?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню