VIDEO LESSON

JavaScriptのDataView.getUint16():バイト順を指定して2バイトの整数を読むの解説動画

再生時間 7:18動画を別のタブで開く ↗
動画の字幕・文字起こしを読む

再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。

  1. 0:00こんにちは。
  2. 0:00今回はジャバスクリプトのデータビューにある、ゲットユーイントじゅうろくを紹介します。
  3. 0:06これは、バイナリデータの中から二バイトを取り出し、整数として読むメソッドです。
  4. 0:12通信データやファイルの先頭部分では、件数や識別番号が二バイトの整数で記録されることがよくあります。
  5. 0:19受け取ったバイトを文字列としてつなげただけでは、正しい数値は得られません。
  6. 0:24このメソッドは、読む位置とバイトの並び順を指定して、データ形式の仕様どおりに数値を取り出せます。
  7. 0:31この動画では、引数と戻り値、バイト順の違い、実例と注意点までを順に解説します。
  8. 0:36バイナリは難しそうに見えますが、読む位置と順序さえ分かれば、一つずつ確実に取り出せます。
  9. 0:42まず土台を押さえましょう。
  10. 0:44バイナリデータの入れ物は、アレイバッファーというバイト列です。
  11. 0:48そのままでは数値として読めないので、データビューという窓口を通して読みます。
  12. 0:53データビューを使えば、好きな位置から、好きな型で値を取り出せます。
  13. 0:58似た仕組みに型付き配列がありますが、そちらは実行環境のバイト順に左右されます。
  14. 1:03データビューはバイト順を自分で指定できる点が大きな違いです。
  15. 1:07ファイル形式や通信の仕様が決まっている場面では、この指定できることが正確な読み取りにつながります。
  16. 1:14まずは窓口を用意する、という流れを覚えてください。
  17. 1:17基本の書き方を見ましょう。
  18. 1:19呼び出しは、ビューに続けてゲットユーイントじゅうろく、かっこの中に二つの引数を書きます。
  19. 1:26第一引数のバイトオフセットは、ビューの先頭から何バイト進んだ位置を読むかです。
  20. 1:32先頭はゼロです。
  21. 1:34第二引数のリトルエンディアンは省略でき、トゥルーならリトルエンディアン、
  22. 1:38フォルスか省略ならビッグエンディアンとして読みます。
  23. 1:43戻り値はゼロ以上六五五三五以下の整数で、型はナンバーです。
  24. 1:48符号がないので負の値は返りません。
  25. 1:51開始位置を二の倍数にそろえる必要はなく、奇数の位置からも読み取れます。
  26. 1:56ここが一番大切なポイントです。
  27. 1:59バイト順とは、二バイトのどちらを上位の桁として扱うかという約束です。
  28. 2:04ビッグエンディアンでは、先にあるバイトを上位として読みます。
  29. 2:09たとえばゼロイチとゼロニの並びなら、一かける二五六たす二で、二五八になります。
  30. 2:16リトルエンディアンでは逆に、後ろのバイトを上位にするので、同じ並びでも五一三になります。
  31. 2:23どちらが正しいかは、データを書いた側の仕様で決まります。
  32. 2:28それらしい数になるまで切り替える運用は、別の入力で誤読のもとです。
  33. 2:33仕様にバイト順を明記し、コードでも引数を明示して意図を残しましょう。
  34. 2:39対応環境を確認しましょう。
  35. 2:41ゲットユーイントじゅうろくは広く利用できる機能で、二千十五年以降、主要ブラウザーの間で使えるようになったとされています。
  36. 2:48現在のクローム、エッジ、ファイアフォックス、サファリで使用できます。
  37. 2:53ジャバスクリプトの組み込み機能なので、ブラウザーでもノードジェイエスでも動きます。
  38. 2:58外部パッケージやビルド処理は不要です。
  39. 3:00ブラウザーでは開発者ツールのコンソールにコードを貼って試せます。
  40. 3:04ノードジェイエスでは、ファイルを保存してノードコマンドで実行します。
  41. 3:09今回の記事ではノードの二十四系を対象にしています。
  42. 3:12まずは手元の環境で小さく試すのがおすすめです。
  43. 3:15古い環境を対象にする場合は、公開前に対応状況を改めて確認してください。
  44. 3:19ここからは実例です。
  45. 3:21先頭の二バイトが件数、続く二バイトが識別番号という、架空のヘッダーを読みます。
  46. 3:27実ファイルやネットワークは使わず、データはコードの中で用意します。
  47. 3:33パケットというバイト列には、対象の前後に読み取り対象外のバイトを置いてあります。
  48. 3:40ヘッダーは、サブアレイで中央の四バイトだけを切り出したものです。
  49. 3:45こうすることで、部分データを扱うときの開始位置と長さの考え方も一緒に確認できます。
  50. 3:52件数のバイトはゼロゼロとゼロ三、識別番号はゼロイチとゼロニです。
  51. 3:58この四バイトを正しく読めるかが、この実例のゴールです。
  52. 4:02読み取り関数の流れを見ましょう。
  53. 4:05パースヘッダーという独自関数では、まず入力の型と長さを確かめます。
  54. 4:09ユーイントはちアレイでなければタイプエラー、四バイトでなければレンジエラーを投げて止めます。
  55. 4:16次にデータビューを作ります。
  56. 4:18このとき、元のバッファーだけでなく、開始位置と長さも一緒に渡すことが重要です。
  57. 4:24最後に、位置ゼロを件数として、位置二を識別番号として、どちらもビッグエンディアンで読みます。
  58. 4:30チェックを先に済ませておくことで、読み取り部分は短く、意図が分かりやすいコードになります。
  59. 4:37スライドでは検証部分を省略しています。
  60. 4:39実行結果を確認しましょう。
  61. 4:41件数は、バイト列がゼロゼロとゼロ三なので三になります。
  62. 4:45識別番号は、ゼロイチとゼロニをビッグエンディアンで読むので二五八です。
  63. 4:51同じ位置をあえてリトルエンディアンで読むと、五一三と表示されます。
  64. 4:56これは間違いではなく、バイト順を変えれば値が変わることを示すための行です。
  65. 5:01結果が仕様と合っているかは、期待する出力と見比べて確かめます。
  66. 5:06なお記事の期待出力は、公式仕様と数値計算に基づくもので、例外については環境差を避けるため名前だけを出力する形になっています。
  67. 5:15計算の根拠まで追えると安心です。
  68. 5:18よくある失敗例です。
  69. 5:19データビューを作るときに、バッファーだけを渡してしまうと、読み取り範囲はヘッダーの四バイトではなく、
  70. 5:24元のパケット全体になってしまいます。
  71. 5:28その状態で位置ゼロを読むと、対象外のエフエフと次のゼロゼロから、六五二八ゼロというまったく違う値を得てしまいます。
  72. 5:36防ぐには、生成時に元のバッファー内での開始位置と対象の長さを渡してください。
  73. 5:42一方、ゲットユーイントじゅうろくに渡す位置は、作ったビューの先頭が基準です。
  74. 5:47そこで再び開始位置を足す必要はありません。
  75. 5:50この二つの基準の違いを混同しないことが大切です。
  76. 5:53範囲外の扱いも知っておきましょう。
  77. 5:56二バイトを読むため、開始位置だけが範囲内でも、次の一バイトが不足すればレンジエラーになります。
  78. 6:03たとえば長さ四のビューで位置三から読むと、位置三と四が必要になり失敗します。
  79. 6:09通信途中のデータを扱うなら、必要な長さがそろってから解析してください。
  80. 6:14また、読み取れた整数が業務上正しいとは限りません。
  81. 6:18件数の上限が百件なら、百一は読み取り自体は成功しても受け付けるべきではありません。
  82. 6:25構造の検査と値の検査は分けて考えましょう。
  83. 6:28なお、このメソッドは同期処理なので、アウェイトは不要です。
  84. 6:32最後に活用場面とまとめです。
  85. 6:34ゲットユーイントじゅうろくは、独自通信形式の件数、バイナリファイルの形式番号、
  86. 6:40機器から届く十六ビットの測定値など、二バイトの符号なし整数を読む場面で使えます。
  87. 6:46負の値や六五五三五を超える値を表す項目には、そのまま当てはめられません。
  88. 6:51実装を育てるなら、まずデータ形式の各項目について、開始位置、必要バイト数、
  89. 6:55バイト順、許容値を書き出してください。
  90. 6:59その定義に合わせて読み取り位置を固定すると、形式が変わったときの修正箇所が明確になります。
  91. 7:05正常なデータだけでなく、一バイト不足した入力や上下限の入力でも確かめてみてください。
  92. 7:11お疲れさまでした。
  93. 7:12位置、順序、範囲。
  94. 7:14この三つをそろえることが、安定した読み取りの土台になります。
日本語字幕をダウンロード(WebVTT)

この動画で学べること

DataView.getUint16()でバイナリの2バイトを整数として読む方法を解説。引数・戻り値、バイト順、ブラウザーとNode.jsでの実行手順、範囲外の例外や部分データの扱いを学べます。

解説記事・サンプルコードを読む:JavaScriptのDataView.getUint16():バイト順を指定して2バイトの整数を読む →