Kotlinにおける ByteArray は、ファイルI/O、ネットワーク通信、暗号処理、画像・音声データなど、バイナリを扱うあらゆる場面の基礎となる型です。
一見シンプルですが、
Array<Byte>との違い- 符号付きByteの罠
- 文字列変換時の注意点
- パフォーマンス面の落とし穴
など、理解が浅いまま使うとバグや性能劣化につながりやすい型でもあります。
この記事では 仕様として正確な説明 + 実務での使い方 を軸にByteArray を体系的に解説します。
目次
ByteArrayとは何か
基本定義
ByteArray は Byte(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 + ビット演算が主流なケースも多い
採用はプロジェクト方針次第。
まとめ
ByteArrayは Kotlinのバイナリ処理の中核Array<Byte>は基本使わない- Byteは符号付き(-128〜127)
- 文字列変換は Charset指定必須
+や変換はコピーコストを意識する
以上、KotlinのByteArrayについてでした。
最後までお読みいただき、ありがとうございました。










