Metin dosyaları Byte Order Mark (BOM) olmadan yazılsın mı?


116

BOM olmadan UTF8 kodlaması ile VB.Net kullanarak bir metin dosyası oluşturmaya çalışıyorum. Biri bana yardım edebilir mi, bunu nasıl yapabilirim?
UTF8 kodlaması ile dosya yazabilirim, ancak Bayt Sırası İşareti bundan nasıl kaldırılır?

edit1: Böyle bir kod denedim;

    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 yalnızca UTF8 kodlamasıyla oluşturulur ve 2.html ANSI kodlama biçimiyle oluşturulur.

Basitleştirilmiş yaklaşım - http://whatilearnttuday.blogspot.com/2011/10/write-text-files-without-byte-order.html


8
Bir malzeme listesi istemiyorsanız, neden GetPreamble () yazıyorsunuz?
Hans Passant

Yanıtlar:


200

Bayt sırası işaretini (BOM) atlamak için akışınız, (bir BOM oluşturmak üzere yapılandırılmış) UTF8Encodingdışında bir örnek kullanmalıdır System.Text.Encoding.UTF8. Bunu yapmanın iki kolay yolu vardır:

1. Uygun bir kodlamayı açıkça belirterek:

  1. Çağrı UTF8Encodingyapıcısı ile Falseiçin encoderShouldEmitUTF8Identifierparametre.

  2. Örneği UTF8Encodingakış yapıcısına iletin.

' 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. Varsayılan kodlamayı kullanarak:

Bir Encodingto StreamWriter's yapıcısı sağlamazsanız , StreamWritervarsayılan olarak BOM olmadan UTF8 kodlaması kullanır, bu nedenle aşağıdakiler de aynı şekilde çalışmalıdır:

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

Son olarak, BOM'un çıkarılmasına UTF-16 için değil, yalnızca UTF-8 için izin verildiğini unutmayın.


Her zaman akıllıca değil: Örneğin My.Computer.FileSystem.WriteAllText, kodlama belirtilmezse BOM'u yazar.
beppe9000

My.Computer.FileSystem.WriteAllTextgeriye doğru VB uyumluluğunu tahmin etmek bu konuda bir istisna olabilir mi? File.WriteAllTextvarsayılan olarak UFT8NoBOM.
jnm2

28

Bunu dene:

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

Sadece Basitçe yöntemi kullanmak WriteAllTextden System.IO.File.

Lütfen File.WriteAllText'teki örneği kontrol edin .

Bu yöntem, Bayt Sırası İşareti (BOM) olmadan UTF-8 kodlamasını kullanır, bu nedenle GetPreamble yönteminin kullanılması boş bir bayt dizisi döndürür. Bir dosyanın başlangıcına bayt sırası işareti gibi bir UTF-8 tanımlayıcısının dahil edilmesi gerekiyorsa, UTF8 kodlamasıyla WriteAllText (String, String, Encoding) yöntemi aşırı yüklemesini kullanın.


Benim ad
alanımdan olan

4

Bununla ilgili ilginç bir not: Garip bir şekilde, System.IO.File sınıfının statik "CreateText ()" yöntemi, BOM olmadan UTF-8 dosyaları oluşturur .

Genel olarak bu, hataların kaynağıdır, ancak sizin durumunuzda en basit çözüm olabilirdi :)


4

EncodingYeni oluştururken bir belirtmezseniz, kullanılan StreamWritervarsayılan Encodingnesne UTF-8 No BOM, üzerinden oluşturulan nesnedir new UTF8Encoding(false, true).

Bu nedenle, kodlama sağlamanızı gerektirmeyen yapıcıların ürün reçetesi kullanımı olmadan bir metin dosyası oluşturmak için:

new StreamWriter(Stream)
new StreamWriter(String)
new StreamWriter(String, Boolean)

Ya belirtmem gerekirse leaveOpen?
binki

@binki bu durumda StreamWriterkullanan varsayılan kodlamayı kullanamazsınız . Belirtmek gerekir new UTF8Encoding(false, true)Kodlamanız belirtmek edebilmek için leaveOpenve reçetesi yok.
JG

3

Bence Roman Nikitin haklı. Yapıcı argümanının anlamı ters çevrilir. False, ürün reçetesi olmadığı ve ürün reçetesi ile doğru anlamına gelir.

ANSI olmayan karakterler içermeyen BOM içermeyen bir dosya ANSI dosyasıyla tamamen aynı olduğu için ANSI kodlaması alırsınız. "Merhaba" dizesinde bazı özel karakterleri deneyin ve ANSI kodlamasının BOM'suz olarak değiştiğini göreceksiniz.


1

BOM'suz XML Kodlama UTF-8
XML verilerini EPA'ya göndermemiz gerekiyor ve bizim girdimizi alan uygulamaları BOM olmadan UTF-8 gerektiriyor. Oh evet, sade UTF-8 herkes için kabul edilebilir olmalı, ancak EPA için değil. Bunu yapmanın cevabı yukarıdaki yorumlarda. Teşekkürler Roman Nikitin .

XML kodlaması için kodun bir C # pasajı:

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

Bunun çıktı dosyasından üç baştaki karakteri gerçekten kaldırıp kaldırmadığını görmek yanıltıcı olabilir. Örneğin, Notepad ++ (www.notepad-plus-plus.org) kullanırsanız, "ANSI'de Kodlama" raporlayacaktır. Sanırım çoğu metin editörünün UTF-8 olup olmadığını söylemek için BOM karakterlerine güveniyor. Bunu açıkça görmenin yolu WinHex (www.winhex.com) gibi ikili bir araç kullanmaktır . Öncesi ve sonrası farkı aradığım için Microsoft WinDiff uygulamasını kullandım.


-1

Girdi metniniz bir bayt sırası işareti içeriyor olabilir. Bu durumda yazmadan önce kaldırmalısınız.


1
Lütfen bana yardım edin. Yazmadan önce nasıl kaldırılır.
Vijay Balkawade

@ user180326 varsayılan okuyucu sizin için bunu zaten filtrelemiyor mu?
binki

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

İstediğiniz sonuçları size verir (sanırım).


1
Bilgisayarımda ANSI dosyaları oluşturuyor
Muflix
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.