みなさま。どうも。ものすごくお久しぶりです。 久々に気まぐれしてみました。というか、大学3年生になったら 気まぐれどころか、ホームページすら管理する暇がなくって...... 最近、アルバイトの仕事でプログラムを作ることになりました。 その仕事の中で78MBものテキストファイルを扱う必要があったのですが 横着してPerlでプログラムを作って読み込もうとしたら もう全然読み込んでくれないのです。 30分くらいほったらかしにしておいてもまだ終わらない...... 限界だな。と思ってしかたなくVBでファイルを読み込ませたのですが 「遅い!遅い!遅い!」 一応は読み込みができるのですが、非常に遅いのです。 「もっと早く読み込まないと使えない!」ということで たしか昔にAPIリファレンスの本で 「ファイルマッピングを使うと高速にファイルI/Oができる」と 書いてあったのを思い出して、早速チャレンジ! 実験してみると、なんと78MBのファイルを あっという間に読み込めるではありませんか!? 「これは面白い。」ということで、今回の気まぐれは ファイルマッピングをやってみることにしました。ファイルマッピングとは?
「で。そのファイルマッピングとはなんぞや?」ということで まずは解説からはじめましょう。 簡単に言うと、ファイルの内容をメモリ内にコピーしてくれるのです。 普通はファイルを読み込もうと思うと、下のようになります。
Dim temp(100) As String
Open "対象ファイル名.txt" For Input As #1
Do While Not EOF(1)
Line Input #1, temp(a)
a=a+1
Loop
Close
|
実験する前に必要なAPI関数を簡単に説明しましょう。
| CreateFileMapping | ファイルマッピングオブジェクトを作成する |
| MapViewOfFile | ファイルビューをマッピングする |
| OpenFileMapping | 名前付きファイルマッピングオブジェクトをオープンする |
| UnmapViewOfFile | ファイルのマップビューをアンマップする |
いきなり解説もなくプログラムです。
Dim hFileMap As Long, hFile As Long, hOpened As Long, nAddress As Long
Dim FileLength As Long, buffer As String
Dim Buffer2 As String
FileLength = FileLen(filename) + 1
'@ファイルのハンドルを取得
hFile = CreateFileLong(filename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0)
'Aオブジェクトを作成する
hFileMap = CreateFileMappingLong(hFile, 0, &H2, 0, 0, "test")
If hFileMap = 0 Then GoTo LabelLast
'Bオブジェクトをオープンして、そのハンドルを取得する
hOpened = OpenFileMapping(FILE_MAP_READ, 0, "test")
If hOpened = 0 Then GoTo LabelLast
'Cファイルビューをマッピングして、その先頭アドレスを取得
nAddress = MapViewOfFile(hOpened, FILE_MAP_READ, 0, 0, 0)
If nAddress = 0 Then GoTo LabelLast
'Dメモリを読み込みたい変数にコピー
buffer = String(Filelength, vbNullChar)
Call MoveMemory(ByVal buffer, ByVal nAddress, FileLength)
Buffer2 = Left(buffer, InStr(buffer, vbNullChar))
'Eファイルビューをアンマップ
Call UnmapViewOfFile(nAddress)
'Fハンドルの解放
LabelLast:
Call CloseHandle(hOpened)
Call CloseHandle(hFileMap)
Call CloseHandle(hFile)
Me.Text1.Text = Buffer2
|