DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

BOM無しのUTF-8でテキストファイルに書き込む

StreamWriterクラスXmlWriterクラスなどを使ってテキストファイルを作成する時、エンコーディングに「System.Text.Encoding.UTF8」を指定すると、BOM(byte order mark、バイトオーダーマーク、バイト順マーク)が付いたUTF-8のテキストファイルが作成されます。ここではBOMが付かないUTF-8(UTF-8N)のテキストファイルを作成する方法を紹介します。

なおBOMというのは、ファイルの先頭に付く数バイトのデータのことで、UTF-8の場合は、「0xEF 0xBB 0xBF」というデータです。詳しくは、Wikipediaの「UTF-8」や「バイトオーダーマーク」等をご覧ください。

もしテキストファイルを作成する方法が分からないという場合は、まず「文字コードを指定してテキストファイルに書き込む」をご覧ください。

エンコーディングを省略する方法

StreamWriterオブジェクトを作成する時、encodingパラメータが省略されると、BOM無しUTF-8で書き込まれるようになります。File.CreateTextメソッドFile.AppendTextメソッドを使ってStreamWriterオブジェクトを取得した時も同じです。

また、File.WriteAllTextメソッドFile.WriteAllLinesメソッドFile.AppendAllTextメソッドで書き込む時も、encodingを省略すると、BOM無しUTF-8で書き込まれます。

なおすでに存在しているファイルに追加書き込みする場合は、そのファイルにBOMが付いていればそのままになります。(以下に紹介するその他の方法でもそうなります。)

BOM無しのUTF-8でテキストファイルを作成する例を以下に示します。

VB.NET
コードを隠すコードを選択
'BOM無しのUTF8でテキストファイルを作成する
Dim sw As New System.IO.StreamWriter("C:\test\1.txt")
'File.CreateTextメソッドを使った時は、次のようになる
'Dim sw As System.IO.StreamWriter = System.IO.File.CreateText("C:\test\1.txt")
sw.Write("こんにちは。")
sw.Close()
C#
コードを隠すコードを選択
//BOM無しのUTF8でテキストファイルを作成する
System.IO.StreamWriter sw = new System.IO.StreamWriter(@"C:\test\1.txt");
//File.CreateTextメソッドを使った時は、次のようになる
//System.IO.StreamWriter sw = System.IO.File.CreateText(@"C:\test\1.txt");
sw.Write("こんにちは。");
sw.Close();

ちなみに次のようにすると、BOMが付加したUTF-8のテキストファイルが作成されます。

VB.NET
コードを隠すコードを選択
'BOMが付加したUTF8でテキストファイルを作成する
Dim sw As New System.IO.StreamWriter( _
    "C:\test\1.txt", False, System.Text.Encoding.UTF8)
sw.Write("こんにちは。")
sw.Close()
C#
コードを隠すコードを選択
//BOMが付加したUTF8でテキストファイルを作成する
System.IO.StreamWriter sw = new System.IO.StreamWriter(
    @"C:\test\1.txt", false, System.Text.Encoding.UTF8);
sw.Write("こんにちは。");
sw.Close();

UTF8Encodingを使用する方法

Encoding.UTF8プロパティを使用する代わりに、自分でUTF8Encodingオブジェクトを作成して使用すれば、BOMを無くすことができます。UTF8Encodingのコンストラクタの引数に何も指定しないか、Falseを指定すると、BOM無しになります。Trueを指定すると、BOM有りになります。

VB.NET
コードを隠すコードを選択
'BOM無しのUTF8でテキストファイルを作成する
Dim enc As System.Text.Encoding = New System.Text.UTF8Encoding(False)
'または、次のようにすることもできる
'Dim enc As System.Text.Encoding = New System.Text.UTF8Encoding()

Dim sw As New System.IO.StreamWriter("C:\test\1.txt", False, enc)
sw.Write("こんにちは。")
sw.Close()
C#
コードを隠すコードを選択
//BOM無しのUTF8でテキストファイルを作成する
System.Text.Encoding enc = new System.Text.UTF8Encoding(false);
//または、次のようにすることもできる
//System.Text.Encoding enc = new System.Text.UTF8Encoding();

System.IO.StreamWriter sw = new System.IO.StreamWriter(
    @"C:\test\1.txt", false, enc);
sw.Write("こんにちは。");
sw.Close();

EncodingオブジェクトがBOMを付加するか調べる

あるEncodingオブジェクトがBOMを付加するかを知るには、Encoding.GetPreambleメソッドが返すバイト型配列の長さを調べます。配列の長さが0ならばBOMは付きません。そうでなければ、BOMが付きます。

VB.NET
コードを隠すコードを選択
Console.WriteLine(System.Text.Encoding.UTF8.GetPreamble().Length)
'"3"となるため、3バイトのBOMが付く

Dim enc As System.Text.Encoding = New System.Text.UTF8Encoding(False)
Console.WriteLine(enc.GetPreamble().Length)
'"0"となるため、BOMは付かない
C#
コードを隠すコードを選択
Console.WriteLine(System.Text.Encoding.UTF8.GetPreamble().Length);
//"3"となるため、3バイトのBOMが付く

System.Text.Encoding enc = new System.Text.UTF8Encoding(false);
Console.WriteLine(enc.GetPreamble().Length);
//"0"となるため、BOMは付かない

Encoding.GetBytesメソッドが返すデータをそのまま書き込む

Encoding.GetBytesメソッドを使うと文字列をバイト型配列に変換することができますが、この場合はBOMを付加しません。よって、Encoding.GetBytesメソッドでバイト型配列に変換して、そのバイト型配列をそのままファイルに書き込めば、BOMが付きません。

ただ、わざわざこのような方法を使うメリットは思いつきません。

VB.NET
コードを隠すコードを選択
'UTF8で文字列をバイト型配列に変換する
Dim utf8Data As Byte() = System.Text.Encoding.UTF8.GetBytes("こんにちは。")
'バイト型配列をそのままファイルに書き込む
System.IO.File.WriteAllBytes("C:\test\1.txt", utf8Data)
C#
コードを隠すコードを選択
//UTF8で文字列をバイト型配列に変換する
byte[] utf8Data = System.Text.Encoding.UTF8.GetBytes("こんにちは。");
//バイト型配列をそのままファイルに書き込む
System.IO.File.WriteAllBytes(@"C:\test\1.txt", utf8Data);

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • このサイトで紹介されているコードの多くは、例外処理が省略されています。例外処理については、こちらをご覧ください。
  • Windows Vista以降でUACが有効になっていると、ファイルへの書き込みに失敗する可能性があります。詳しくは、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。