🐥
「バイナリ」と「bytes」の違いをWebエンジニアが理解する - 曖昧さを解消する完全ガイド
はじめに
「CSVファイルをバイナリで送信」「ファイルサイズは1024bytes」
こういった表現を見て、「バイナリ」と「bytes」の使い分けに迷ったことはありませんか?
実は多くのWebエンジニアが、この2つの概念を曖昧に使っています。本記事では、その違いを明確にし、適切に使い分けられるようになることを目指します。
1. 一言で理解する違い
// バイナリ = 「どんな形式?」(表現方法)
const number = 65;
console.log(number.toString(2)); // "1000001" ← バイナリ表現
// bytes = 「どれくらい?」(データ量)
const text = "Hello";
console.log(new TextEncoder().encode(text).length); // 5 ← 5bytes
覚え方:
- バイナリ(Binary) = 形式・フォーマットの話
- bytes = サイズ・単位の話
2. バイナリ(Binary)の理解
2.1 バイナリ = データの表現形式
// 同じデータの異なる表現
const value = 65;
// 10進数表現
console.log(value); // 65
// 2進数表現(バイナリ)
console.log(value.toString(2)); // "1000001"
// 16進数表現
console.log(value.toString(16)); // "41"
// 文字表現
console.log(String.fromCharCode(value)); // "A"
2.2 「バイナリ形式」vs「テキスト形式」
Webエンジニアが最も遭遇する対比:
// ユーザーデータの例
const userData = {
id: 123,
name: "Alice",
email: "alice@example.com"
};
// テキスト形式(JSON)
const textFormat = JSON.stringify(userData);
console.log(textFormat);
// '{"id":123,"name":"Alice","email":"alice@example.com"}'
// → 人間が読める
// バイナリ形式(Protocol Buffersを想定)
// [08 7B 12 05 41 6C 69 63 65 1A 11 61 6C 69 63 65 40 65 78 61 6D 70 6C 65 2E 63 6F 6D]
// → 人間には読めないが効率的
2.3 実務での「バイナリ」の使用例
// ファイル読み込みでの使い分け
const file = event.target.files[0];
// テキストとして読む
const textReader = new FileReader();
textReader.readAsText(file); // テキスト形式
// バイナリとして読む
const binaryReader = new FileReader();
binaryReader.readAsArrayBuffer(file); // バイナリ形式
// APIレスポンスの処理
fetch('/api/data.json')
.then(res => res.json()); // JSON(テキスト)形式
fetch('/api/image.png')
.then(res => res.arrayBuffer()); // バイナリ形式
3. Bytes(バイト)の理解
3.1 Bytes = データサイズの単位
// 1 byte = 8 bits = 0〜255の値を表現可能
// 文字のbyte数を確認
console.log(new TextEncoder().encode("A").length); // 1 byte
console.log(new TextEncoder().encode("あ").length); // 3 bytes
console.log(new TextEncoder().encode("🎉").length); // 4 bytes
// ファイルサイズの確認
const file = document.getElementById('fileInput').files[0];
console.log(`ファイルサイズ: ${file.size} bytes`);
3.2 なぜ「byte」という単位?
// bitだと細かすぎる
// 1文字 = 8 bits は扱いにくい
// byteにまとめることで
// 1文字 = 1 byte(ASCII)
// メモリアドレッシングも効率的
// 実例:色の表現
const red = 255; // 1 byte (8 bits)
const green = 128; // 1 byte (8 bits)
const blue = 0; // 1 byte (8 bits)
// RGB合計 = 3 bytes
3.3 サイズ単位の階層
// 人間が読みやすいサイズ表示
function formatFileSize(bytes) {
const units = ['bytes', 'KB', 'MB', 'GB'];
let size = bytes;
let unitIndex = 0;
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024;
unitIndex++;
}
return `${size.toFixed(2)} ${units[unitIndex]}`;
}
console.log(formatFileSize(1500)); // "1.46 KB"
console.log(formatFileSize(1048576)); // "1.00 MB"
4. 実際のコードでの使い分け
4.1 Protocol Buffersでの例
// .protoファイルでの定義
message FileData {
string filename = 1;
bytes content = 2; // "bytes"型 = バイト配列を格納
int64 size = 3; // ファイルサイズ(bytes単位)
}
// 使用時の説明
// ✅ 正しい説明
"contentフィールドには、ファイルのバイナリデータを格納します"
"sizeフィールドには、ファイルサイズをbytes単位で格納します"
// ❌ 間違った説明
"contentフィールドには、ファイルのbytesデータを格納します" // bytesは形式ではない
"sizeフィールドには、ファイルのバイナリサイズを格納します" // バイナリは単位ではない
4.2 APIドキュメントでの使い分け
## ファイルアップロードAPI
### リクエスト仕様
- Method: POST
- Content-Type: multipart/form-data
- 最大ファイルサイズ: 10MB (10,485,760 bytes)
### レスポンス仕様
- 形式: JSON または バイナリ形式(Accept headerで指定)
- JSONの場合: Base64エンコードされたデータ
- バイナリの場合: 生のバイナリデータ
4.3 エラーメッセージでの使い分け
// ✅ 正しいエラーメッセージ
if (file.size > MAX_SIZE) {
throw new Error(`ファイルサイズが上限(${MAX_SIZE} bytes)を超えています`);
}
if (!isBinaryFormat(file)) {
throw new Error('バイナリ形式のファイルをアップロードしてください');
}
// ❌ 間違ったエラーメッセージ
"ファイルが10MBバイナリを超えています" // バイナリは単位ではない
"100bytesフォーマットで送信してください" // bytesは形式ではない
5. gRPC/ConnectRPCでの実例
5.1 Connect (JSON) vs Connect (Binary)
// この設定の意味を正確に理解する
const transport = createConnectTransport({
baseUrl: "http://localhost:8080",
useBinaryFormat: false, // false = JSON形式, true = バイナリ形式
});
// 実際の通信
// JSON形式の場合
POST /api.UserService/GetUser
Content-Type: application/json
Content-Length: 15 bytes // サイズはbytes単位
{"id": "123"} // データはJSON形式
// バイナリ形式の場合
POST /api.UserService/GetUser
Content-Type: application/connect+proto
Content-Length: 5 bytes // サイズはbytes単位
[08 7B] // データはバイナリ形式
5.2 パフォーマンス比較での表現
// 測定結果の正しい表現
const results = {
jsonFormat: {
size: "125KB", // サイズ(bytes系単位)
format: "JSON", // 形式
parseTime: "3.2ms"
},
binaryFormat: {
size: "45KB", // サイズ(bytes系単位)
format: "Protocol Buffers", // 形式
parseTime: "1.1ms"
}
};
// ✅ 正しい説明
"バイナリ形式の方が、JSONより64%小さいサイズで転送できます"
// ❌ 間違った説明
"bytes形式の方が効率的です" // bytesは形式ではない
6. よくある間違いと正しい使い方
6.1 会話での間違い
// ❌ よくある間違い
"データを100バイナリ送信します" // バイナリは単位ではない
"このAPIはbytes形式を返します" // bytesは形式ではない
"バイナリサイズは1KBです" // 「バイナリデータのサイズ」が正しい
// ✅ 正しい表現
"100bytesのデータを送信します"
"このAPIはバイナリ形式でデータを返します"
"バイナリデータのサイズは1KBです"
6.2 コメントでの使い分け
/**
* 画像ファイルを処理する関数
*
* @param {File} imageFile - 処理する画像ファイル
* @param {Object} options - オプション設定
* @param {boolean} options.returnBinary - trueの場合バイナリ形式で返す
* @param {number} options.maxSizeBytes - 最大ファイルサイズ(bytes)
*
* @returns {Promise<string|ArrayBuffer>}
* Base64文字列(テキスト形式)またはArrayBuffer(バイナリ形式)
*/
async function processImage(imageFile, options = {}) {
// ファイルサイズチェック(bytes単位)
if (imageFile.size > options.maxSizeBytes) {
throw new Error(`ファイルサイズが上限を超えています`);
}
// バイナリデータとして読み込み
const binaryData = await imageFile.arrayBuffer();
// 返却形式の選択
if (options.returnBinary) {
return binaryData; // バイナリ形式で返す
} else {
// Base64(テキスト形式)に変換して返す
return btoa(String.fromCharCode(...new Uint8Array(binaryData)));
}
}
7. 実践的なデバッグ
7.1 Chrome DevToolsでの確認
// Networkタブでの見方
// ヘッダー情報
Content-Type: application/octet-stream // バイナリ形式
Content-Length: 2048 // 2048 bytes
// Responseタブ
// テキスト形式 → 内容が表示される
// バイナリ形式 → [Binary content] と表示
// Sizeカラム
// 常にbytes系の単位で表示(1.5 KB, 324 B など)
7.2 ログ出力のベストプラクティス
// デバッグログの正しい書き方
function logDataInfo(data) {
const bytes = new TextEncoder().encode(JSON.stringify(data));
console.log({
format: "JSON", // 形式
size: `${bytes.length} bytes`, // サイズ
preview: data // 内容
});
// バイナリ表現も確認したい場合
console.log({
binaryRepresentation: Array.from(bytes).map(b =>
b.toString(16).padStart(2, '0')
).join(' ')
});
}
まとめ:正しい使い分けのための指針
クイックリファレンス
| 文脈 | バイナリ(Binary) | Bytes |
|---|---|---|
| データ形式の説明 | "バイナリ形式で保存" ✅ | "bytes形式で保存" ❌ |
| データサイズの説明 | "100バイナリ" ❌ | "100 bytes" ✅ |
| 対比表現 | "JSONではなくバイナリ" ✅ | "KBではなくbytes" ✅ |
| エラーメッセージ | "バイナリ形式が不正" ✅ | "10MB以下にしてください" ✅ |
最終チェックリスト
// 自分の文章をチェック
const checkUsage = (text) => {
// ❌ NGパターン
const ngPatterns = [
/\d+\s*バイナリ/, // "100バイナリ"
/bytes形式/, // "bytes形式"
/バイナリサイズ/, // "バイナリサイズ"(単独使用)
];
// ✅ OKパターン
const okPatterns = [
/バイナリ形式/, // 形式の話
/\d+\s*bytes/, // サイズの話
/バイナリデータ/, // データの話
];
};
これらの違いを意識することで、技術文書やコードコメントがより正確で伝わりやすくなります。特にgRPCやファイル処理を扱う際は、この使い分けが重要です!
Discussion