ダウンロードした.datファイルは、JVLinkの出力を順番に記録したものなので、格納されているデータの順番はバラバラです。
そこで、私はRubyスクリプト「DataLab_Index.rb」で検索用の情報を作って利用しています。
Rubyスクリプト「DataLab_Index.rb」、Downloadフォルダ内の各.datファイルに対応した.idxファイルを出力します。
この.idxファイルは、JRA-VAN SDKに含まれているJV-Data仕様書でレコードのキーとされている情報で検索するための情報です。
.datファイル内に同じキーの情報があった場合、作成日時が新しいデータが優先されます。
また、作成日時が同じか不明な場合は、最近取得したデータが優先されます。
.idxファイルは、「キー情報」+「,」+「データのある位置(先頭からのバイト数。10文字)」+「改行」の形式になっています。つまり、同じ.idxファイル内では、1行の長さが固定されています。また、一応、キー情報で昇順にソートされた形で格納されています。
このスクリプトは、古い.idxファイルがあっても無視して、各.datファイルを頭から調べ直しています。
.datファイルは末尾に追記されていくだけのファイルなので、既存の.idxファイルを再利用すればもっと効率がよく作成できるでしょう。
とりあえず、頻繁にする作業でもないので問題になっていません。
(1) Downloadフォルダ内に.datファイルが存在する状態でスクリプトを実行します。オプションはありません。
>ruby DataLab_Index.rb
(2) 進行状況が表示されます。括弧内の数字は、「(有効データ数/全データ数)」です。
#JRA-VANからダウンロードしたデータのインデックスを作る
#DATファイルのフォーマット定義。作成日時(位置,サイズ)、インデックス@(位置,サイズ)…
DATFormat = { "TK" => [ 3, 8, 11, 16 ], \
"RA" => [ 3, 8, 11, 16 ], \
"SE" => [ 3, 8, 11, 16, 28, 12 ],
"HR" => [ 3, 8, 11, 16 ], \
"H1" => [ 3, 8, 11, 16 ], \
"H6" => [ 3, 8, 11, 16 ], \
"O1" => [ 3, 8, 11, 16 ], \
"O2" => [ 3, 8, 11, 16 ], \
"O3" => [ 3, 8, 11, 16 ], \
"O4" => [ 3, 8, 11, 16 ], \
"O5" => [ 3, 8, 11, 16 ], \
"O6" => [ 3, 8, 11, 16 ], \
"UM" => [ 3, 8, 11, 10 ], \
"KS" => [ 3, 8, 11, 5 ], \
"CH" => [ 3, 8, 11, 5 ], \
"BR" => [ 3, 8, 11, 6 ], \
"BN" => [ 3, 8, 11, 6 ], \
"HN" => [ 3, 8, 11, 8 ], \
"SK" => [ 3, 8, 11, 10 ], \
"RC" => [ 3, 8, 11, 21, 93, 8 ], \
"HC" => [ 3, 8, 11, 23 ], \
"WH" => [ 3, 8, 11, 16 ], \
"WE" => [ 3, 8, 11, 23 ], \
"AV" => [ 3, 8, 11, 16, 35, 2 ], \
"JC" => [ 3, 8, 11, 26 ], \
"DM" => [ 3, 8, 11, 16 ], \
"YS" => [ 3, 8, 11, 14 ], \
"TC" => [ 3, 8, 11, 16 ], \
"CC" => [ 3, 8, 11, 16 ] }
#Downloadフォルダ内の.datファイルを列挙する
Dir.glob('Download/*.dat').each { |name|
if FileTest.file?(name) then
recodeid = File.basename(name)[0,2].upcase
if DATFormat.key?(recodeid) then
fmt = DATFormat[recodeid]
#DATファイルを読み込む
dat_count = 0
print "[", name, "]読み込み中..."
index = Hash.new([0, "00000000"])
open(name, "rb") { |datfile|
position = 0
datfile.each { |line|
line_date = line[fmt[0],fmt[1]]
line_index = line[fmt[2],fmt[3]]
if fmt.size > 5 then
line_index += line[fmt[4],fmt[5]]
end
#インデックス情報更新
old_index = index[line_index]
if old_index[1] < line_date then
index[line_index] = [position, line_date]
end
position = datfile.pos
dat_count = dat_count + 1
}
}
print "終了\n"
#インデックスをソート
index_keys = index.keys
index_keys.sort!
#インデックスファイルを書き込む
idxname = 'Download/' + recodeid + ".idx"
print "[", idxname, "]書き込み中..."
open(idxname, "w") { |idxfile|
index_keys.each { |key|
idxfile.printf("%s,%010d\n", key, index[key][0])
}
}
print "終了(", index.size, "/", dat_count, ")\n"
end
end
}
Windows版Rubyでは、2GBを超えるファイルで、File.sizeやIO#posが正しく動作しないようです。
そのため、このスクリプトはサイズが2GBを超える.datファイルに対して正常に動作しません。
H1.datファイルのサイズが2GBを超えているような場合は、「"H1" => [ 3, 8, 11, 16 ],
\」の行を削除(またはコメントアウト)してください。(その場合は、H1のインデックスファイルが作成されません。)

(C) 2006-2008 NARITA, Takuro
E-Mail:narita@a1.mbn.or.jp