コンピューティング環境において、データを媒体に格納する際の方法には主に二つのアプローチが存在します。これらはしばしば混同されますが、技術的な目的と動作原理は明確に区別される必要があります。
核心となる定義
- バイナリモード:データを特定の文字セットとして解釈することなく、生のバイト列(Byte Stream)のまま転送する処理です。このモードは、JPEG 画像や音声ファイル、シリアライズされたオブジェクトなど、人間が直接読むことを想定していない構造体データの保存に不可欠です。ここでは、OS が行う改行コードの変換などのフィルター処理は無効化されます。
- エンコーディング仕様:テキストデータをデジタル信号に変換するためのマッピングルールです。Unicode の UTF-8 や、レガシーな ASCII などが代表例であり、特定の記号に対し何バイトの値を割り当てるかを定義します。テキストファイルを読み書きする際には、この仕様が一致しないと文字化けが発生します。
テキスト処理においてはエンコーディングを明示的に指定する必要がありますが、バイナリ操作では「データそのもの」を扱います。したがって、非構造化データや暗号化情報を扱う際は、エンコーディングの制約を受けずに正確に複製できるバイナリ I/O が最適解となります。
実装パターン
以下に、両言語におけるローレベルなファイル入出力の実装例を示します。
from pathlib import Path
def persist_binary_content(filepath: str) -> None:
"""生バイトデータをストレージへ格納する"""
# 固定長のパケットヘッダを模したダミーデータ
payload = bytes([0xCA, 0xFE, 0xBA, 0xBE])
with open(filepath, mode="wb") as stream:
stream.write(payload)
def retrieve_binary_content(filepath: str) -> bytes:
"""ストレージから生バイトデータを復元する"""
with open(filepath, mode="rb") as stream:
raw_data = stream.read()
return raw_data
# メイン処理
target_file = "snapshot_01.dat"
persist_binary_content(target_file)
print(f"Read Result: {retrieve_binary_content(target_file).hex()}")
#include <iostream>
#include <fstream>
#include <vector>
int execute_binary_io() {
const char* destination = "snapshot_01.dat";
// バイナリデータの準備
std::vector<unsigned char> packet(4);
packet[0] = 0xCA;
packet[1] = 0xFE;
packet[2] = 0xBA;
packet[3] = 0xBE;
// 書き込みフェーズ (バイナリフラグ必須)
{
std::ofstream output(destination, std::ios::binary);
if (output.is_open()) {
output.write(reinterpret_cast<const char*>(packet.data()), packet.size());
output.close();
}
}
// 読み込みフェーズ
{
std::ifstream input(destination, std::ios::binary);
if (input.is_open()) {
std::vector<unsigned char> restored(packet.size());
input.read(reinterpret_cast<char*>(restored.data()), restored.size());
// 検証出力 (16 進数表示)
std::cout << "Restored Hex: ";
for (auto byte : restored) {
std::cout << std::hex << (int)byte << " ";
}
std::cout << std::endl;
}
}
return 0;
}