KotlinのByteArrayについて

採用はこちら

Kotlinにおける ByteArray は、ファイルI/O、ネットワーク通信、暗号処理、画像・音声データなど、バイナリを扱うあらゆる場面の基礎となる型です。

一見シンプルですが、

  • Array<Byte> との違い
  • 符号付きByteの罠
  • 文字列変換時の注意点
  • パフォーマンス面の落とし穴

など、理解が浅いまま使うとバグや性能劣化につながりやすい型でもあります。

この記事では 仕様として正確な説明 + 実務での使い方 を軸にByteArray を体系的に解説します。

目次

ByteArrayとは何か

基本定義

ByteArrayByte(8bit整数)を要素に持つプリミティブ配列です。

val bytes: ByteArray = ByteArray(10)

特徴まとめ

項目内容
要素型Byte(符号付き8bit)
JVM上の実体byte[]
サイズ固定長
要素のnull不可
パフォーマンス非常に高い

要素はnull不可ですが、配列参照自体は ByteArray? としてnullableにできます。

ByteArrayとArrayの違い

ByteArray

val a = ByteArray(3)
  • JVMでは byte[]
  • オートボクシングなし
  • 高速・省メモリ
  • I/O・通信・暗号向き

Array

val b = arrayOf(1.toByte(), 2.toByte(), 3.toByte())
  • JVMでは Byte[]
  • 各要素がオブジェクト
  • 遅く、メモリ使用量も多い

結論

バイナリデータを扱うなら ByteArray 一択
Array<Byte> はほぼ使いません。

ByteArrayの生成方法

サイズ指定(初期値は0)

val bytes = ByteArray(5)

初期化ラムダ付き

val bytes = ByteArray(5) { it.toByte() }
// [0, 1, 2, 3, 4]

リテラルから生成

val bytes = byteArrayOf(1, 2, 3, 4)

Byteは符号付きである点に注意

範囲

-128 ~ 127
val b1: Byte = 127
// val b2: Byte = 128 // コンパイルエラー

よくある罠

val b = 255.toByte()
println(b) // -1

これはエラーではなく、下位8bit(0xFF)を符号付きとして解釈した結果です。

符号なしとして扱う場合

val unsigned = b.toInt() and 0xFF // 255

バイナリ処理では「値」より「ビット」を意識します。

基本操作

要素アクセス

val bytes = byteArrayOf(10, 20, 30)
println(bytes[0]) // 10

サイズ

bytes.size

ループ

for (b in bytes) {
    println(b)
}
for (i in bytes.indices) {
    println("index=$i value=${bytes[i]}")
}

StringとByteArrayの相互変換

String → ByteArray

val text = "Hello"
val bytes = text.toByteArray(Charsets.UTF_8)

ByteArray → String

val restored = bytes.toString(Charsets.UTF_8)

Charsetは必ず指定する
省略すると環境依存になり、文字化けの原因になります。

ファイルI/OでのByteArray

import java.io.File

読み込み

val bytes = File("sample.bin").readBytes()

書き込み

File("out.bin").writeBytes(bytes)

※ Androidではパス・権限・Storage APIの制約がある点に注意。

ストリーム処理とバッファ

val buffer = ByteArray(1024)
val len = inputStream.read(buffer)
  • I/Oバッファの基本形
  • ByteArray が最も効率的

コピー・部分取得・結合

コピー

val copy = bytes.copyOf()

部分コピー

val part = bytes.copyOfRange(0, 4)

結合

val merged = bytes1 + bytes2

+新しい配列を生成してコピーします。
大量結合ではパフォーマンスに注意。

Collection変換

val list = bytes.toList()
val array = list.toByteArray()
  • 変換コストあり
  • 高頻度処理では避ける

暗号・ハッシュとByteArray

import java.security.MessageDigest

val digest = MessageDigest.getInstance("SHA-256")
val hash = digest.digest("hello".toByteArray())

暗号・署名・ハッシュ系APIは ほぼすべて ByteArray を使用します。

UByteArrayについて

val ubytes = UByteArray(4) { it.toUByte() }
  • 読みやすさは向上
  • Javaとの相互運用で変換が必要になることが多い
  • 実務では ByteArray + ビット演算 が主流なケースも多い

採用はプロジェクト方針次第。

まとめ

  • ByteArrayKotlinのバイナリ処理の中核
  • Array<Byte> は基本使わない
  • Byteは符号付き(-128〜127)
  • 文字列変換は Charset指定必須
  • + や変換はコピーコストを意識する

以上、KotlinのByteArrayについてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次