Nimでバイトオーダ(エンディアン)を意識してデータ読み書きする
概要
Nimでstreamsモジュールを使ってのデータ読み書きについてまとめる
バイトオーダ(エンディアン)を意識する必要がある
streamsの読み書きのエンディアンを調べる
streamsモジュールには何のエンディアンでデータを読み書きするのか説明がない
調べた
数値の読み書きのエンディアン
little.nimimport streams
block:
var strm = newFileStream("9.dat", fmWrite)
strm.write(9'u32)
strm.close()
block:
var strm = newFileStream("9.dat", fmRead)
echo strm.readUint32()
strm.close()
このコードを実行した結果生成される 9.dat
のバイナリを調べると以下のようになる
9.sh$ xxd 9.dat
00000000: 0900 0000 ....
一番下位のバイトが先頭に来ている
そして readUint32
で取得した値を出力すると 9
が出力される
文字列の読み書きのエンディアン
str.nimimport streams
block:
var strm = newFileStream("hello.dat", fmWrite)
strm.write("hello")
strm.close()
block:
var strm = newFileStream("hello.dat", fmRead)
echo strm.readStr(5)
strm.close()
このコードを実行した結果生成される hello.dat
のバイナリを調べると以下のようになる
9.sh$ xxd hello.dat
00000000: 6865 6c6c 6f hello
helloがhelloの順序のまま格納されている
そして readStr
で取得した値を出力すると hello
が出力される
よってreadStrはビッグエンディアンとして読み込む
数値をビッグエンディアンで読み取る
big.nimimport streams, endians
block:
var strm = newFileStream("big.dat", fmWrite)
strm.write(0'u8)
strm.write(0'u8)
strm.write(0'u8)
strm.write(9'u8)
strm.close()
block:
var strm = newFileStream("big.dat", fmRead)
var src = strm.readUint32()
echo "littleEndian32: " & $src
var dst: uint32
bigEndian32(addr(dst), addr(src))
echo "bigEndian32: " & $dst
strm.close()
result.txtlittleEndian32: 150994944
bigEndian32: 9
ビッグエンディアンで書き込んだデータを
readUint32
で読み取ると当然
9
にならない