Month: 4月 2016

Goでバイナリを固定長で読んでいくときのメモ

バイナリの先頭nバイトを読みたいときというのがあると思う。先頭4バイトを読むとデータのサイズが入ってて、その後nバイトがデータとか、そういうやつ。固定長で読む良い方法があんまりなくて(あったらおしえてくれ)、自分でsliceを所望のサイズでmakeして、そこにio.Readする。ちょっとはまったのでメモ。

 

  file, _ := os.Open("test.bin")

  // 例1
  buf := make([]byte, 256)
  read_size, _ := file.Read(buf)
  fmt.Println(read_size, "bytes read.", string(buf))

  // 例2
  buf2 := make([]byte, 256)
  read_size2, _ := io.ReadFull(file, buf2)
  fmt.Println(read_size2, "bytes read.", string(buf2))

 

何も考えずにやると上の例1みたいになると思うが、これだとバッファが埋まるまで読んでくれないことがあってはまる(read_sizeが256にならない場合がある)。

そもそも、io.Readは1回呼ばれたときの読み出しサイズが保証されていないので、io.Readで読み出されるサイズはなんかよくわからないけど読み出し元の種類とか状況によるっぽい。数バイトくらいなら問題ないことが多いが、サイズが大きくなってくると1回のio.Readでバッファを埋められないことがでてくる。なので、io.ReadFullを使う(例2)。これならバッファが埋まるまでio.Readを繰り返し呼んでくれる。テキストファイルの読み込みとかだとio.Readを直接使うことはほとんどないが、バイナリを扱うときもできるだけ使わないのがよさそう。

ちなみに[]byteをstringにcastできるらしい。ASCII専用だろうが。

 

あと、2/4/8バイトを読んで数値として解釈するのはもっと簡単で、encoding/binaryをimportして、

  var num uint16
  binary.Read(file, binary.LittleEndian, &num)

とすればnumの型の分(この場合は2バイト)だけ読み出してreaderを進めてくれる。楽。

追記(2016/04/16):

encoding/binary/binary.goを読むと、io.ReadFullを使っていることがわかる。なるほど。

あと、binary.Readは各整数型以外にもそれぞれのスライスに対応しているらしい。

  num := make([]uint16, 3)
  binary.Read(file, binary.LittleEndian, &num)
  fmt.Println(num)
  // => [14648 24880 25442]

Windows 10 Insider preview build 14316でsubsystem for linuxを試す

タイトルが長い。

まずInsider previewのfast ringに入り、build 14316のアップデートを適用する。すると、Windowsの機能?のところにWindows Subsystem for Linux (Beta)という超かっこいい項目があるので、有効にする。

Windows-features

起動したところ

起動してunameを打ったところ

あとは普通にBash on Ubuntu on Windowsとかいうプログラムが追加されているので、起動して適当にあそぶ。

試した範囲では、build-essentialをはじめとする各種パッケージは普通にaptで入るし、それでzsh, emacs, gitあたりは普通にconfigure/makeできて動いた。emacsをちょっと使ったら表示がぶっ壊れたりしてたし、動作はだいぶ怪しいところが当然あるが、普通にうごくのがすごい。

 

Zsh

sudo apt-get install -y git-core gcc make autoconf yodl libncursesw5-dev texinfo
ls
mkdir zsh-build
cd zsh-build/
git clone git://zsh.git.sf.net/gitroot/zsh/zsh
cd zsh/
./Util/preconfig
./configure
make
make install

emacs 24.5

curl -O http://ftp.jaist.ac.jp/pub/GNU/emacs/emacs-24.5.tar.gz
tar xzf emacs-24.5.tar.gz
cd emacs-24.5
./configure --without-x
make
make install
emacs
emacs -version

git

git clone https://github.com/git/git.git --depth 1
cd git/
make configure
./configure --with-curl --prefix=$HOME/local
make
make install

まるでubuntuのように動く。ただデフォルトのリポジトリがクソ重いので、riken様のリポジトリに変えておくとよい。普通にubuntuと同じように/etc/apt/sources.listを変えるだけ。

root@localhost:~# cat /etc/apt/sources.list
deb http://ftp.jaist.ac.jp/pub/Linux/ubuntu/ trusty main restricted universe multiverse
deb http://ftp.jaist.ac.jp/pub/Linux/ubuntu/ trusty-updates main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu trusty-security main restricted universe multiverse

emacsが入ると自分のinit.elを試したくなるのが人情というものだろう。私のはこれ: https://github.com/naotaco/emacs.d

いつも通りel-getを~/.emacs.d/以下にcloneして、このinit.elを置いて起動したら普通に動いた(ただしgit1.9.5以上が必要なので、自分でビルドする必要がある)。すごい。

emacs

emacs

すぐ表示が壊れる

すぐ表示が壊れる

Auto completionもHelmも動く。

Auto completionもHelmも動く。

なにがなんだかわからないが、本当に動いててすごい。使ってて頭が混乱する。あと、Ctrl+Aがどっかにキーを奪われているのかbash/emacsで使えないのが厳しい。まあそれを言えば、コマンドプロンプト並の機能しかないターミナル自体がそもそも相当厳しいが、まあさすがにこの辺はそのうちなんとかなるだろう。とりあえず無限の可能性を感じる。

GitLabとGit LFSを使ってExcelなどのバイナリでできたドキュメントの世代管理をする

前置き

皆さんも業務上やむを得ずWord, ExcelやPowerpointでドキュメントを作っていることと思います。他にもなんかよく分からない画像だったりとか、Astahとかそういうやつとか。とにかく望むと望むまいと僕たちはプロプライエタリなバイナリに囲まれて生きています。

まあその手のドキュメントは作ったり読んだりしてる限り別にいいんですが、だいたい世代管理が困難に近いです。MicrosoftのSharepointとかいう地上最低の操作性を誇るWebアプリを使う 1など、まあ手が無いこともないのですが、いろいろと厄介です。で、そういうファッキンバイナリィドキュメンツが数十GB単位で貯まってきた頃に事故があって、誰かが共有フォルダのファイルを消したりぶち壊したりしてしまったりなんだりして、上司が「ちょっとこれいい感じに管理する方法考えといて」とか無茶なことを言ってくるわけです。

後半に私情が挟まりましたが、とにかくバイナリをどう管理するかは我々の会社生活を左右する死活問題なわけなので、真面目に考えます。

Continue reading

Notes:

  1. なんとドキュメントのロックができるので、他人との衝突を避けることができます!!