tar(4)
tar の構造
基本的に1つの変数を除いて、すべてヌル文字終端の文字列として格納されて、その基数は8進。ただし幅が足りない場合はヌル文字を省略できる、という感じらしい。
ヘッダは512バイトの固定長、データは512バイトを1ブロックとするが、ヘッダに元の大きさが格納されているので、詰め物を除去できないとかの問題はない。
ヘッダの先頭から1024バイトの0(ヌル文字)が連続したら、そこをTARの終点とする、みたいな処理になってる。厳密に実装するとヘッダを読み込んだらまず512バイトすべて0か探索して、もしそうなら次の512バイトを読んで、それも0かチェックする、みたいな処理になる。ちょーめんどい。今回はsizeの最初の文字がヌル文字なら終了する、というふうにした。
C#だとこんな感じでファイル一覧を吐ける。
null終端文字列を切る方法を知らないのでてきとーに関数作った。IndexOfしてSubstringしてるだけ。
using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read)) { bool loop = true; while(loop) { byte[] buffer = new byte[512]; fs.Read(buffer, 0, buffer.Length); if(buffer[124] != '\0') { string name = Encoding.ASCII.GetString(buffer, 0, 100); string mode = Encoding.ASCII.GetString(buffer, 100, 8); string uid = Encoding.ASCII.GetString(buffer, 108, 8); string gid = Encoding.ASCII.GetString(buffer, 116, 8); string size = Encoding.ASCII.GetString(buffer, 124, 12); string mtime = Encoding.ASCII.GetString(buffer, 136, 12); string chksum = Encoding.ASCII.GetString(buffer, 148, 8); string typeflag = Encoding.ASCII.GetString(buffer, 156, 1); string linkname = Encoding.ASCII.GetString(buffer, 157, 100); string magic = Encoding.ASCII.GetString(buffer, 257, 6); string version = Encoding.ASCII.GetString(buffer, 263, 2); string uname = Encoding.ASCII.GetString(buffer, 265, 32); string gname = Encoding.ASCII.GetString(buffer, 297, 32); string devmagor = Encoding.ASCII.GetString(buffer, 329, 8); string devminor = Encoding.ASCII.GetString(buffer, 337, 8); string prefix = Encoding.ASCII.GetString(buffer, 345, 155); UInt32 data_size_byte = Convert.ToUInt32(size.clip_null_char(), 8); UInt32 data_size_block = (data_size_byte + 511) / 512; Console.WriteLine(name.clip_null_char() + " " + data_size_byte); fs.Position += data_size_block * 512; } else { loop = false; } } }
普段使ってる圧縮展開ソフトではTARにできなかった。ファイル数が多すぎたみたい。動画を切り出した連番画像なので3700個もある。
今回はbashのtarコマンドで作ったけど、*.jpgで全部突っ込んだら単純なASCII文字列でソートした順番になった。自然数順じゃないので、必要に応じて0埋めとかにリネームしておく必要があるかも。ちゃんとしたやりかたはありそうだけど。
すべて512バイト単位ってのは便利でいいなぁ。格納時に気をつければシーケンシャルリードできるし、まるちめでぃあかーどでも早そう。ファイル名を指定したランダムリードはクッソ遅そう。今回はシーケンシャルで十分だけど。
とりあえず眠いのでマタアシタ~
0 件のコメント:
コメントを投稿