Pythonでバイナリ入出力のクラス作った
Pythonでバイナリデータ入力とバイナリデータ出力するクラスを作ってみました。
ちなみにPythonで作った初めてのクラスです。
from struct import * class ByteIO: def __init__(self, name, mode): enable_mode = ("rb","wb","ab") if mode not in enable_mode: raise Exception('ByteIO: file mode error. mode="' + mode + '" is unsupport.') self.file = open(name, mode) def __del__(self): self.close() def close(self): self.file.close() def writeLong(self, num): self.file.write(pack('>Q',num)) def writeInt(self, num): self.file.write(pack('>L',num)) def writeShort(self, num): self.file.write(pack('>H',num)) def writeByte(self, num): self.file.write(pack('>B',num)) def writeIntByCount(self,nByteCount,num): for cnt in range(0,nByteCount): self.file.write(pack('B',(num>>((nByteCount-cnt-1)<<3))&0xff)) def writeDouble(self, real_num): self.file.write(pack('>d',real_num)) def writeFloat(self, real_num): self.file.write(pack('>f',real_num)) def readIntByCount(self,nByteCount): num=0 for cnt in range(0,nByteCount): num<<=8 num|=(ord(self.file.read(1))&0xFF) return num def readLong(self): return unpack('>Q',self.file.read(8))[0] def readInt(self): return unpack('>L',self.file.read(4))[0] def readShort(self): return unpack('>H',self.file.read(2))[0] def readByte(self): return unpack('>B',self.file.read(1))[0] def readDouble(self): return unpack('>d',self.file.read(8))[0] def readFloat(self): return unpack('>f',self.file.read(4))[0] # テスト if __name__ == '__main__': # Python バイナリ書き込みテスト bout = ByteIO("test.dat", "wb") bout.writeByte(0xAB) bout.close() # Python バイナリ追加書き込みテスト bout = ByteIO("test.dat", "ab") bout.writeShort(0xCDEF) bout.writeInt(0x01234567) bout.writeLong(0x89ABCDEF01234567) bout.writeFloat(89.012345678901234) bout.writeDouble(89.012345678901234) bout.close() # Python バイナリ読み込みテスト bin = ByteIO("test.dat", "rb") print("0x%02X, 0x%04X, 0x%08X, 0x%016X, %.16f, %.16f " % ( bin.readByte(), bin.readShort(), bin.readInt(), bin.readLong(), bin.readFloat(), bin.readDouble())) bin.close()
【試行錯誤メモ】
writeIntByCount()
1バイトずつ書き込むのは遅いだろと思って文字列作ってから書き込むとエラー。
MS932ではそんなコード対応してないよ、って言われてしまう。
※ソースはUTF-8だけど、Windowsで確認しているからMS932言われるんだと思う。
chr()を使っても同じでした。
row型の文字列作れれば出力できると思って探してみたけど見つからず。
結局ちまちまと1バイトずつ出力するようにしてみました。
【感想】
Pythonってソースコード短いねぇ。
self毎回指定しているのはちょっと煩わしいけど。
PHPも$this書くし、クラスの書き方はJavaが簡潔で好きだなぁ。
【課題】
浮動小数点の読み書きも付けないとナ〜
→付けました。2012/09/28
【参考】
強火で進め:バイナリデータの出力処理
http://d.hatena.ne.jp/nakamura001/20080610/1213113005
Python ライブラリリファレンス(日本語)※ver2.5
http://www.python.jp/doc/2.5/lib/module-struct.html