Menulis file teks tanpa Byte Order Mark (BOM)?

116

Saya mencoba membuat file teks menggunakan VB.Net dengan pengkodean UTF8, tanpa BOM. Adakah yang bisa membantu saya, bagaimana melakukan ini?
Saya dapat menulis file dengan pengkodean UTF8 tetapi, bagaimana cara menghapus Byte Order Mark darinya?

edit1: Saya telah mencoba kode seperti ini;

    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 dibuat hanya dengan pengkodean UTF8 dan 2.html dibuat dengan format pengkodean ANSI.

Pendekatan yang disederhanakan - http://whatilearnttuday.blogspot.com/2011/10/write-text-files-without-byte-order.html

Vijay Balkawade
sumber
8
Jika Anda tidak menginginkan BOM, mengapa Anda menulis GetPreamble ()?
Hans Passant

Jawaban:

200

Untuk menghilangkan byte order mark (BOM), streaming Anda harus menggunakan instance UTF8Encodingselain System.Text.Encoding.UTF8(yang dikonfigurasi untuk menghasilkan BOM). Ada dua cara mudah untuk melakukannya:

1. Secara eksplisit menentukan pengkodean yang sesuai:

  1. Panggil UTF8Encodingkonstruktor dengan Falsefor the encoderShouldEmitUTF8Identifierparameter.

  2. Meneruskan UTF8Encodinginstance ke konstruktor aliran.

' 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. Menggunakan pengkodean default:

Jika Anda tidak memasok Encodingke StreamWriter's konstruktor sama sekali, StreamWriterakan dengan menggunakan standar encoding UTF8 tanpa BOM, sehingga berikut ini harus bekerja sama dengan baik:

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

Terakhir, perhatikan bahwa menghilangkan BOM hanya diperbolehkan untuk UTF-8, bukan untuk UTF-16.

stakx - tidak lagi berkontribusi
sumber
Tidak selalu bijaksana: misalnya My.Computer.FileSystem.WriteAllTextmenulis BOM jika tidak ada pengkodean yang ditentukan.
beppe9000
My.Computer.FileSystem.WriteAllTextmerupakan pengecualian dalam hal ini, mungkin menebak kompatibilitas VB ke belakang? File.WriteAllTextdefaultnya adalah UFT8NoBOM.
jnm2
28

Coba ini:

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
Roman Nikitin
sumber
6

Cukup gunakan metode WriteAllTextdari System.IO.File.

Silakan periksa sampel dari File.WriteAllText .

Metode ini menggunakan pengkodean UTF-8 tanpa Byte-Order Mark (BOM), jadi menggunakan metode GetPreamble akan mengembalikan array byte kosong. Jika perlu menyertakan pengenal UTF-8, seperti tanda urutan byte, di awal file, gunakan metode WriteAllText (String, String, Encoding) yang berlebihan dengan encoding UTF8.

Joe.wang
sumber
Yang dari namespace saya memang menggunakan BOM
beppe9000
4

Catatan menarik sehubungan dengan ini: anehnya, metode "CreateText ()" statis dari kelas System.IO.File membuat file UTF-8 tanpa BOM.

Secara umum ini adalah sumber bug, tetapi dalam kasus Anda ini bisa menjadi solusi yang paling sederhana :)

Tao
sumber
4

Jika Anda tidak menentukan Encodingsaat membuat baru objek StreamWriterdefault yang Encodingdigunakan adalah UTF-8 No BOMyang dibuat melalui new UTF8Encoding(false, true).

Jadi untuk membuat file teks tanpa BOM, gunakan konstruktor yang tidak mengharuskan Anda menyediakan encoding:

new StreamWriter(Stream)
new StreamWriter(String)
new StreamWriter(String, Boolean)
JG di SD
sumber
Bagaimana jika saya perlu menentukan leaveOpen?
binki
@binki dalam hal ini Anda tidak dapat menggunakan pengkodean default yang StreamWriterdigunakan. Anda harus menentukan new UTF8Encoding(false, true)agar pengkodean Anda dapat menentukan leaveOpendan tidak memiliki BOM.
JG di SD
3

Saya pikir Roman Nikitin benar. Arti dari argumen konstruktor dibalik. False artinya tidak ada BOM dan true means dengan BOM.

Anda mendapatkan pengkodean ANSI karena file tanpa BOM yang tidak berisi karakter non-ansi persis sama dengan file ANSI. Coba beberapa karakter khusus dalam string "hai di sana" Anda dan Anda akan melihat pengkodean ANSI berubah menjadi tanpa-BOM.

jos
sumber
1

XML Encoding UTF-8 tanpa BOM
Kita perlu mengirimkan data XML ke EPA dan aplikasinya yang membutuhkan input kita membutuhkan UTF-8 tanpa BOM. Oh ya, UTF-8 biasa seharusnya dapat diterima oleh semua orang, tetapi tidak untuk EPA. Jawaban untuk melakukan ini ada di komentar di atas. Terima kasih Roman Nikitin .

Berikut adalah potongan C # kode untuk pengkodean 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();  
    }    

Untuk melihat apakah ini benar-benar menghapus tiga karakter utama dari file keluaran bisa menyesatkan. Misalnya, jika Anda menggunakan Notepad ++ (www.notepad-plus-plus.org), ini akan melaporkan "Encode in ANSI". Saya kira sebagian besar editor teks mengandalkan karakter BOM untuk mengetahui apakah itu UTF-8. Cara untuk melihat ini dengan jelas adalah dengan alat biner seperti WinHex (www.winhex.com). Karena saya mencari perbedaan sebelum dan sesudah saya menggunakan aplikasi Microsoft WinDiff .

Jerry Banasik
sumber
-1

Mungkin teks masukan Anda berisi tanda urutan byte. Dalam hal ini, Anda harus menghapusnya sebelum menulis.


sumber
1
Tolong bantu saya. Cara menghapusnya sebelum menulis.
Vijay Balkawade
@ user180326 bukankah pembaca default sudah memfilternya untuk Anda?
binki
-1
Dim sWriter As IO.StreamWriter = New IO.StreamWriter(shareworklist & "\" & getfilename() & ".txt", False, Encoding.Default)

Memberi Anda hasil seperti yang Anda inginkan (menurut saya).

Mwenyeji
sumber
1
Di PC saya, ini membuat file ANSI
Muflix