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 件のコメント:
コメントを投稿