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付になる。
マイクロソフトの Visual Studio 2022 のドキュメントでも、次のように明記されている。
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なしになる。
