Step 3: Core Technology
15. Blob と File の違い:
「画像データ」の正体を掴む
JavaScriptで画像を扱っていると必ず遭遇する「Blob」と「File」。最初は「どっちも画像データでしょ?」と軽く考えていましたが、厳密には明確な違いがありました。この違いを整理したことで、ライブラリのドキュメントの読み解きや、バグの特定が格段にスムーズになった記録です。
1. Blob とは「不変な生のデータの塊」
Blob (Binary Large Object) は、その名の通り「巨大なバイナリデータの塊」を指します。中身がテキストであれ画像であれ、コンピュータにとっては単なる 0 と 1 の羅列に過ぎません。
重要なのは、Blobは 不変(Immutable) であるという点です。一度作成されたBlobの中身を直接書き換えることはできません。Web開発においては、Canvasから画像を生成したり、データベース(IndexedDBなど)に一時的なデータを保存したりする際に、この「生のデータ」という形式が重宝されます。
2. File とは「名札(メタデータ)が付いた Blob」
一方、File インターフェースは、Blobを継承(extend)した特別なオブジェクトです。簡単に言うと、「Blob + OS上でのファイル情報」 です。
OSがファイルを管理するためには、中身(バイナリ)だけでなく、「名前」「サイズ」「最終更新日時」といった情報が必要です。これらを併せ持っているのが File オブジェクトです。インフラエンジニアの視点で言えば、純粋なデータである「パケット」に、宛先や制御情報を加えた「フレーム」のような関係に近いかもしれません。
コードで見る生成元による違い
【File】ユーザーが選択したファイル(名札あり)
// から取得する場合
const file = inputElement.files[0];
console.log(file.name); // "profile.jpg"
console.log(file.lastModified); // 1673456789000
console.log(file instanceof Blob); // true (FileはBlobの一種) 【Blob】Canvasやプログラムで生成したデータ(名札なし)
// Canvasから画像を生成する場合
canvas.toBlob((blob) => {
console.log(blob.size); // データサイズはわかる
console.log(blob.type); // "image/png"
// console.log(blob.name); // ⚠️ undefined (名前はない)
}, "image/png"); 3. 注意点:File と Blob の相互変換
フロントエンドの実務において、「Blobを受け取る関数にFileを渡す」のは問題ありませんが、その逆は工夫が必要です。
- File は Blob の子: 多くのAPI(
URL.createObjectURLやFileReader)は、引数に Blob を要求しますが、File を渡しても動作します。File は Blob の性質をすべて持っているからです。 - Blob を File に変換する: キャンバスで加工した Blob を、サーバーへ「ファイル」として送信したい場合があります。その際は
new File()コンストラクタを使用して、名前を付けてあげる必要があります。
// Blob に名前を付けて「ファイル」に格上げする
const fileFromBlob = new File([myBlob], "processed_image.jpg", {
type: "image/jpeg",
}); 4. 実務での活用:猫の手ツール開発での気づき
「猫の手ツール」では、この違いを厳密に使い分けています。
ユーザーがアップロードした瞬間は File として扱い、元のファイル名を引き継ぎます。しかし、Canvas上で「証明写真のサイズにトリミング」し、新しい画像を生成した瞬間に、それは Blob という「名無しのデータ」に変わります。
最後、ユーザーがダウンロードボタンを押すときに、再び new File や a.download = "filename" の処理で「名札」を付け直してあげる。このデータの流れを整理できたことで、「なぜか保存時に名前が変になる」「拡張子が消える」といったトラブルを未然に防げるようになりました。
まとめ
「Blobは中身のデータ」「Fileは名前付きの器」。
このシンプルな原則を理解するだけで、フロントエンドにおけるバイナリデータの扱いはぐっと楽になります。インフラのネットワークパケットを解析するように、データの階層構造を意識すること。それが、強固なWebアプリを作るための第一歩なのだと実感しています。