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でテキストファイルを作成する例を以下に示します。
'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()
//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のテキストファイルが作成されます。
'BOMが付加したUTF8でテキストファイルを作成する Dim sw As New System.IO.StreamWriter( _ "C:\test\1.txt", False, System.Text.Encoding.UTF8) sw.Write("こんにちは。") sw.Close()
//BOMが付加したUTF8でテキストファイルを作成する System.IO.StreamWriter sw = new System.IO.StreamWriter( @"C:\test\1.txt", false, System.Text.Encoding.UTF8); sw.Write("こんにちは。"); sw.Close();
Encoding.UTF8プロパティを使用する代わりに、自分でUTF8Encodingオブジェクトを作成して使用すれば、BOMを無くすことができます。UTF8Encodingのコンストラクタの引数に何も指定しないか、Falseを指定すると、BOM無しになります。Trueを指定すると、BOM有りになります。
'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()
//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.GetPreambleメソッドが返すバイト型配列の長さを調べます。配列の長さが0ならばBOMは付きません。そうでなければ、BOMが付きます。
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は付かない
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メソッドを使うと文字列をバイト型配列に変換することができますが、この場合はBOMを付加しません。よって、Encoding.GetBytesメソッドでバイト型配列に変換して、そのバイト型配列をそのままファイルに書き込めば、BOMが付きません。
ただ、わざわざこのような方法を使うメリットは思いつきません。
'UTF8で文字列をバイト型配列に変換する Dim utf8Data As Byte() = System.Text.Encoding.UTF8.GetBytes("こんにちは。") 'バイト型配列をそのままファイルに書き込む System.IO.File.WriteAllBytes("C:\test\1.txt", utf8Data)
//UTF8で文字列をバイト型配列に変換する byte[] utf8Data = System.Text.Encoding.UTF8.GetBytes("こんにちは。"); //バイト型配列をそのままファイルに書き込む System.IO.File.WriteAllBytes(@"C:\test\1.txt", utf8Data);