VIDEO LESSON
JavaScriptのTextEncoder.encodeInto():用意したバッファーへUTF-8を書き込むの解説動画
再生時間 7:56動画を別のタブで開く ↗
動画の字幕・文字起こしを読む
再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。
- 0:00こんにちは。
- 0:00今回はジャバスクリプトのテキストエンコーダー・エンコードイントゥーを紹介します。
- 0:07これは、文字列を、あらかじめ用意したバッファーへユーティーエフエイトで直接書き込むメソッドです。
- 0:15新しい配列を作るのではなく、渡したユーインティーエイトアレイの中身が書き換わります。
- 0:22戻り値では、入力をどこまで読み進めたかと、何バイト書けたかが分かります。
- 0:27この動画では、基本の使い方から、日本語と絵文字を含む文字列を小さなバッファーへ分けて書く方法、
- 0:33容量不足への対処までを、実行結果と一緒に学びます。
- 0:39ブラウザーとノード・ジェイエスの両方で使えます。
- 0:43まず、使いどころです。
- 0:45バイナリーデータを作るときは、文字列をバイト列へ変換する必要があります。
- 0:51例えば、先頭に管理情報を置き、その後ろにメッセージを入れる形式では、あらかじめ用意した領域へ文字列を書き込みたくなります。
- 1:00似たメソッドのエンコードは、毎回新しいバイト列を作ります。
- 1:05一方、エンコードイントゥーは、既存のバッファーへ直接書くので、領域の使い回しや、
- 1:09書き込む位置の指定ができます。
- 1:14通信やファイル保存で、決められたサイズの枠へデータを収める場面で役立つ違いです。
- 1:20結果は文字列ではなく、数値のバイト列になる点も押さえてください。
- 1:25引数と戻り値のルールです。
- 1:28呼び出し方は、エンコーダー・ドット・エンコードイントゥーで、括弧の中に変換したい文字列と、
- 1:33書き込み先のバッファーを渡します。
- 1:38注意したいのは、戻り値がバイト列ではないことです。
- 1:43戻り値は、リードとリトゥンという二つの数値を持つ、進捗を表すオブジェクトです。
- 1:50データ本体は、渡したバッファーの中に入ります。
- 1:54画面の例では、エーと、あ、という二文字を処理して、リードが二、リトゥンが四になりました。
- 2:01書き込まれた四バイトを取り出すと、六十五、二百二十七、百二十九、百三十という並びが確認できます。
- 2:10処理は同期で進み、プロミスは返りません。
- 2:13ここが一番のポイントです。
- 2:15入力の位置と出力の長さは、数える単位が違います。
- 2:19例として、エー、あ、笑顔の絵文字、ビー、という文字列を考えます。
- 2:24ジャバスクリプトのレングスでは、エーが一、あが一、絵文字が二、ビーが一で、
- 2:28合計五です。
- 2:31一方、ユーティーエフエイトでは、それぞれ一バイト、三バイト、四バイト、一バイトとなり、
- 2:35全体で九バイト必要です。
- 2:40ですから、残りの文字列を取り出す位置にはリードを、書き込んだ領域を取り出す長さにはリトゥンを使います。
- 2:48この二つを取り違えると、入力を飛ばしたり、不要なバイトまで渡したりする原因になります。
- 2:55対応環境を確認します。
- 2:56このメソッドは、主要ブラウザーとノード・ジェイエスの両方で利用でき、ノード・ジェイエスではバージョン十二・十一・ゼロで追加されました。
- 3:05追加パッケージやインポートは不要です。
- 3:07ただし、テキストエンコーダー自体が存在しても、エンコードイントゥーに対応しているとは限りません。
- 3:13古いブラウザーや組み込みのウェブビューを対象にする場合は、画面のように、
- 3:17メソッド自体の有無まで確認してください。
- 3:20また、テキストエンコーダーが扱う文字コードはユーティーエフエイト専用です。
- 3:25シフトジスなどを指定して出力する機能はない点も覚えておきましょう。
- 3:29記事の中心となる実行例を読みます。
- 3:32五バイトの作業用バッファーを用意し、エー、あ、絵文字、ビーという文字列を、
- 3:36繰り返し書き込んでいきます。
- 3:40各回では、オフセット以降の残りをスライスで渡し、返ってきたリードだけ入力の位置を進め、
- 3:44リトゥンを合計に加えます。
- 3:48進捗がゼロのままでは無限ループになるため、リードがゼロならエラーで止める安全策も入れています。
- 3:55このコードはノード・ジェイエスの実機でも、記事の期待出力と同じ結果になることを確認済みです。
- 4:02ブラウザーのコンソールでも、そのまま実行できます。
- 4:06次のセクションで、各回の数字を詳しく追います。
- 4:10実行結果を読み解きます。
- 4:12一回目は、エーと、あ、までが書き込まれ、リードが二、リトゥンが四でした。
- 4:18この時点でバッファーの残りは一バイトですが、次の絵文字には四バイト必要なので、
- 4:22ここで止まります。
- 4:26ユーティーエフエイトのバイト列が、文字の途中で切れることはありません。
- 4:32二回目は、残りの絵文字とビーが処理され、リードが三、リトゥンが五になりました。
- 4:39絵文字がユーティーエフシックスティーンでは二つのコード単位に数えるため、
- 4:43二回目のリードは三です。
- 4:47合計のリードが入力のレングス五と一致すれば、入力をすべて処理できたことになります。
- 4:54失敗例を見ます。
- 4:55あ、という一文字には三バイト必要です。
- 4:58二バイトしかないバッファーを渡すと、リードもリトゥンもゼロになり、バッファーの中身はゼロのまま変わりません。
- 5:06ここで大切なのは、容量不足そのものは例外にならないことです。
- 5:11エラーが出ないからこそ、戻り値を見て検出する設計が必要です。
- 5:15また、同じ入力と、同じ容量で再試行し続けても、結果は変わりません。
- 5:20容量不足を扱うときは、再試行すること自体ではなく、次の試行で容量をどう変えるかを決めておく必要があります。
- 5:28先ほどのループの進捗チェックは、この停滞を無限ループにしないための仕掛けでした。
- 5:34書き込んだ後の注意点です。
- 5:36有効な出力は、先頭からリトゥンバイトまでだけです。
- 5:40使い回したバッファーの残りの領域には、以前のデータが残っている可能性があります。
- 5:46送信や保存の対象は、必ずこの有効範囲に絞ってください。
- 5:50画面の例でも、バッファー全体にはゼロが残っていますが、正しい結果は先頭の二バイトだけです。
- 5:57もう一つ、サブアレイで切り出した部分は、元のメモリーを共有するビューです。
- 6:03切り出したつもりで保存しておいても、後からバッファーを上書きすると、中身まで変わってしまいます。
- 6:10非同期の送信へ渡す場合は、処理が終わるまで再利用を待つか、独立した配列へコピーする設計にしてください。
- 6:17容量の見積もりと、書き込み位置の指定です。
- 6:21文字列のレングスと同じバイト数では、日本語や絵文字を含む文字列を収めきれません。
- 6:28一括変換の上限の目安は、レングスの三倍です。
- 6:32ただし、大きな入力ではメモリーの消費も増えるため、小さなバッファーで分割する方式との使い分けを考えてください。
- 6:41位置の指定にはサブアレイが便利です。
- 6:45画面の例では、先頭二バイトを管理情報用に空けたビューを渡し、そこから書き始めています。
- 6:52元の配列の三バイト目に、エイチのバイト値である百四が入っていることが確認できます。
- 6:59全文が必須のデータでは、リードとレングスを照合し、未完了なら領域を広げるか、
- 7:04入力を拒否する方針も決めておきましょう。
- 7:09まとめです。
- 7:10テキストエンコーダー・エンコードイントゥーは、用意したバッファーへ文字列をユーティーエフエイトで書き込むメソッドで、
- 7:16戻り値のリードとリトゥンから進捗を確認できます。
- 7:23入力の位置はユーティーエフシックスティーンのコード単位、出力の長さはバイト数と、
- 7:27単位が違う点が最大の注意点でした。
- 7:31容量不足は例外にならず、進捗ゼロとして返ること、有効な範囲はリトゥンバイトまでであることも押さえてください。
- 7:39練習として、主例のバッファーを四バイトや九バイトに変え、各回のリードとリトゥンを予想してみると理解が深まります。
- 7:48入力と出力を別々に追えるようになると、バッファーを使う処理を組み立てやすくなります。
- 7:54お疲れさまでした。
この動画で学べること
TextEncoder.encodeInto()で文字列を既存のバッファーへ書き込む方法を解説。日本語・絵文字のバイト数、容量不足への対応、ブラウザーとNode.jsの実行手順を学べます。
解説記事・サンプルコードを読む:JavaScriptのTextEncoder.encodeInto():用意したバッファーへUTF-8を書き込む →