バイナリファイルの読み込みメモ
pmdローダーを作る前に。
import java.io.File; import java.io.FileInputStream; import java.nio.ByteBuffer; // 全部読み込む File f=new File(path); int length=(int)f.length(); byte[] buf=new byte[length]; FileInputStream fs=new FileInputStream(path); fs.read(buf); fs.close(); // nio.ByteBuffer化する ByteBuffer bb=ByteBuffer.wrap(buf); // ByteBufferから任意の型の値を取り出して、現在位置を進める // float bb.getFloat(); // byte(2^8) bb.get() // WORD(2^16) (bb.get()<<8)+bb.get() // DWORD(2^32) (bb.get()<<24)+(bb.get()<<16)+(bb.get()<<8)+bb.get() // String(length) new String(buf, bb.position(), length, Charset.forName("MS932")); bb.position(bb.position()+lenght);
こんだけできれば十分かな。
あとはごりごり書けばよし。
微妙に間違っていた
Javaはunsignedが無いので修正。
Javaのbyte型ってCのunsigned charかと思ったら、signed char型なのね。
でJavaのchar型は敢えて言えば、Cのwchar_tになるか(utf16格納用なので)。
wchar_tだと実装系依存になりそうだから2byteの整数型であるところの
unsinged shortが対応するか。
あと、endian的な問題に対処してscala的には下記のようになった。
さらにendianでもう一手必要だったのを追記。
class ByteReader(val path :File){ val CP932=Charset.forName("MS932") val buf=new Array[Byte](path.length.asInstanceOf[Int]) val io=new FileInputStream(path) io.read(buf) io.close() // 追記。getFloatに必要だった val bb=ByteBuffer.wrap(buf).order(ByteOrder.LITTLE_ENDIAN) def pos :Int=bb.position def isEnd :Boolean=bb.position>=bb.capacity def getString(length :Int) :String={ val ret=new String(buf, bb.position, length, CP932) bb.position(bb.position()+length) ret } def get() :Int={ val b=bb.get() if(b>=0) b else b+256 } def getWORD() :Int={ val b0=get() val b1=get() (b1<<8) + b0 } def getDWORD() :Int={ val b0=get() val b1=get() val b2=get() val b3=get() (b3<<24) + (b2<<16) + (b1<<8) + b0 } def getFloat() :Float=bb.getFloat() def getVector2() :Vector2=Vector2(getFloat(), getFloat()) def getVector3() :Vector3=Vector3(getFloat(), getFloat(), getFloat()) def getRGB() :RGB=RGB(getFloat(), getFloat(), getFloat()) def getRGBA() :RGBA=RGBA(getFloat(), getFloat(), getFloat(), getFloat()) }