1.はじめに
UTF-8 の文字コードのファイルには、BOM (Byte Order Mark) がある場合とない場合がある。
Unicode の規格では、BOM は、推奨されないが、許容されている。
今回、必要があり、色々な OS や言語で、UTF-8 の文字コードのファイルを作成した時、BOM が記録されるか、されないか、を調べた。
2.色々な OS や言語での BOM
2.1 Windows 10, Visual Studio, C++, _wfopen (_tfopen)
// Visual Studio 2005 以降 保存 FILE *fp = _wfopen(name, _ L"w, ccs=UTF-8"); if (fp == NULL) { // エラー処理 } fwprintf_s(fp, L"ABC漢字123\n"); fclose(fp); // 読み込み FILE *fp = _wfopen(name L"r, ccs=UTF-8");
保存では、 BOM付になる。
マイクロソフトのドキュメントでも、次のように明記されている。
Unicode モードで書き込むように開かれたファイルには、自動的に BOM が書き込まれます。
読み込みは、BOM があっても無くても問題はない。
BOM によって文字コードの自動判定まで行っている。
2.2 Windows 10, Visual Studio, C++, _wfopen (_tfopen), BOM 無しにする方法
_wfopen() を使い、BOM 無しにするには、次の二つの方法がある。
(1) fseek() でBOM を上書き
FILE *fp = _wfopen(name, _L"w, ccs=UTF-8"); if (fp == NULL) { // エラー処理 } // BOM (EF BB BF) を上書き fseek(fp, 0L, SEEK_SET); fwprintf_s(fp, L"ABC漢字123\n"); fclose(fp);
(2) バイナリで保存
FILE *fp = _wfopen(name, _L"wb");
2.3 Windows 10, Visual Studio, C++, MFC
CStdioFile file(_tfopen( name, L"w, ccs=UTF-8")); file.WriteString(L"ABC☖☗漢字123\n"); file.Close();
保存では、 BOM付になる。
読み込みは、BOM があっても無くても問題はない。
2.4 Windows 10, Visual Studio, C++, Stream
std::wofstream stream("bom_test_15-2.txt"); const std::codecvt_utf8<wchar_t> * converter = new std::codecvt_utf8<wchar_t>; const std::locale utf8_locale = std::locale(std::locale::empty(), converter); stream.imbue(utf8_locale); if (! stream.bad()) { std::wstring str = L"ABC☖☗漢字123\n"; stream << str; stream.close(); }
保存では、BOM無しになる。
読み込みは、BOM があっても無くても問題はない。
2.5 Windows 10, Visual Studio, C#
Encoding enc = Encoding.GetEncoding("utf-8"); StreamWriter writer = new StreamWriter(@"D:\ファイル名", false, enc); writer.WriteLine("ABC☖☗漢字123"); writer.Close();
保存では、 BOM付になる。
StreamReader sr = new StreamReader(name, Encoding.GetEncoding("utf-8")); string str = sr.ReadToEnd(); sr.Close();
読み込みは、BOM があっても無くても問題はない。
2.6 Android OS, Java
// 保存 String fileName = “android_bom_test.txt"; String str = "ABC☖☗漢字123\n"; OutputStream out = null; try { out = context.openFileOutput(fileName, Context.MODE_PRIVATE); out.write(str.getBytes()); out.close(); } catch (Exception e) { }
保存では、 BOMなしになる。
// 読み込み FileReader reader = new FileReader(path); char[] buffer = new char[BUF_SIZE]; reader.read(buffer); String str = new String(buffer); reader.close();
読み込みは、BOM があっても無くても問題はない。
2.7 macOS / iOS, Objective-C
// 保存 NSString *str = @"ABC☖☗漢字123\n"; NSError *error = nil; BOOL result = [str writeToFile: file_name atomically: YES encoding: NSUTF8StringEncoding error: &error];
保存では、 BOMなしになる。
// 読み込み NSError *error = nil; NSString *str = [NSString stringWithContentsOfFile: file_name encoding: NSUTF8StringEncoding error: &error ];
読み込みは、BOM があっても無くても問題はない。
2.8 Perl
!/usr/bin/env perl use utf8; use Encode; open(file, "> $file_name"); print file Encode::encode( 'UTF-8', "ABC☖☗漢字123\n" ); close(file);
保存では、 BOMなしになる。
open(rfile, "<:utf8", $file_name);
読み込みは、BOM があっても無くても問題はない。
2.9 PHP
<?php $file_name = "php_bom_test.txt"; file_put_contents($file_name, "ABC☖☗漢字123\n"); // 保存では、 BOMなしになる。 $str = file_get_contents($file_name); print ("str=".$str."\n"); // 読み込みは、BOMがあっても無くても問題はない。 ?>
2.10 JavaScript
const save = document.createElement('a'); save.href = URL.createObjectURL(new Blob(["ABC☖☗漢字123\n"], {type: 'text/plain'})); save.download = 'JavaScriptTest.txt'; // file name save.style.display = 'none'; document.body.appendChild(save); save.click();
保存では、 BOMなしになる。