73

StreamWriter とバイト オーダー マークに問題があります。ドキュメントには、Encoding.UTF8 エンコーディングではバイト オーダー マークが有効になっていると記載されているようですが、ファイルが書き込まれているときにマークがあるものとないものがあります。

次の方法でストリーム ライターを作成しています。

this.Writer = new StreamWriter(this.Stream, System.Text.Encoding.UTF8);

何が起こっているのかについてのアイデアをいただければ幸いです。

4

10 に答える 10

114

誰かがすでに指摘しているように、encoding引数なしで呼び出すとうまくいきます。ただし、明示的にしたい場合は、次のことを試してください。

using (var sw = new StreamWriter(this.Stream, new UTF8Encoding(false)))

BOMを無効にするには、new UTF8Encoding(false)Encoding.UTF8Encodingだけでなく、を使用して構築することが重要です。これは、encoding引数なしでStreamWriterを呼び出すのと同じで、内部的には同じことをしているだけです。

BOMを有効にするには、new UTF8Encoding(true)代わりにを使用します。

更新:Windows 10 v1903以降、notepad.exeにUTF-8として保存する場合、BOMバイトが代わりにオプトイン機能になりました。

于 2012-07-25T17:14:51.500 に答える
17

コンストラクターが UTF-8 BOM を追加しないのは、呼び出し時にストリームが位置 0 にない場合だけです。たとえば、次のコードでは、BOM は書き込まれません。

using (var s = File.Create("test2.txt"))
{
    s.WriteByte(32);
    using (var sw = new StreamWriter(s, Encoding.UTF8))
    {
        sw.WriteLine("hello, world");
    }
}

他の人が言ったようにStreamWriter(stream)、エンコーディングを指定せずにコンストラクターを使用している場合、BOM は表示されません。

于 2011-03-10T21:45:14.873 に答える
16

私の答えは、必要な情報がすべて含まれている HelloSam のものに基づいています。OPが求めているのは、BOMがファイルに確実に出力されるようにする方法だと私だけが信じています。

したがって、false を UTF8Encoding ctor に渡す代わりに、true を渡す必要があります。

    using (var sw = new StreamWriter("text.txt", new UTF8Encoding(true)))

以下のコードを試して、結果のファイルを 16 進エディターで開き、BOM を含むファイルと含まないファイルを確認してください。

class Program
{
    static void Main(string[] args)
    {
        const string nobomtxt = "nobom.txt";
        File.Delete(nobomtxt);

        using (Stream stream = File.OpenWrite(nobomtxt))
        using (var writer = new StreamWriter(stream, new UTF8Encoding(false)))
        {
            writer.WriteLine("HelloПривет");
        }

        const string bomtxt = "bom.txt";
        File.Delete(bomtxt);

        using (Stream stream = File.OpenWrite(bomtxt))
        using (var writer = new StreamWriter(stream, new UTF8Encoding(true)))
        {
            writer.WriteLine("HelloПривет");
        }
    }
于 2014-03-19T19:31:27.737 に答える
6

すべてのファイルに対して StreamWriter の同じコンストラクターを使用していますか? ドキュメントには次のように記載されているためです。

UTF-8 エンコーディングと BOM を使用して StreamWriter を作成するには、StreamWriter(String, Boolean, Encoding) などのエンコーディングを指定するコンストラクターの使用を検討してください。

私も少し前に同じような状況でした。Stream.WriteStreamWriter の代わりにメソッドを使用することになり、結果を書き込むEncoding.GetPreamble()前にEncoding.GetBytes(stringToWrite)

于 2011-03-10T21:40:33.477 に答える
2

ファイルが既に存在し、BOM が含まれていない場合、上書きされたときに BOM が含まれないようです。

于 2011-06-23T13:59:11.193 に答える
1

発生しない状況を教えてください。私が見つけることができるプリアンブルが存在しない唯一のケースは、ライターに何も書かれていない場合です (Jim Mischel は、別の、論理的で、あなたの問題である可能性が高いものを見つけたようです。答えを参照してください)。

私のテストコード:

var stream = new MemoryStream();
using(var writer = new StreamWriter(stream, System.Text.Encoding.UTF8))
{
    writer.Write('a');
}
Console.WriteLine(stream.ToArray()
    .Select(b => b.ToString("X2"))
    .Aggregate((i, a) => i + " " + a)
    );
于 2011-03-10T21:45:46.853 に答える