■ 現在のこのページの役立ち度:
表示されない場合こちらのリンクからもご覧になれます。
■ このページの役立ち度を評価する:
役立ち度を評価してください。
(1(左):あまり役立たない - 5(右):大変役立った):
■ ページの共有:
[ サイト内検索 ]
カスタム検索
#2720-1高速なファイルからの読み込み(1行ずつ)法Pooh1999-08-05(木) 17:14
     #2737-1RE#2720:高速なファイルからの読み込み(1行ずつ)法せつら1999-08-05(木) 20:35
     #2758-1RE#2737:高速なファイルからの読み込み(1行ずつ)法Pooh1999-08-06(金) 10:54
#2720-1
高速なファイルからの読み込み(1行ずつ)法
この掲示板には初めての投稿になります。今後ともよろしくお願いします。

    同様の質問をfj.comp.lang.visualbasicにもしましたが、こちらのほうが回答が
    早そうなので、投稿させていただきます。

SOFTBANKの参考書やMSDN・インターネット上で色々と探しましたが、解決方法が
みつからないため、もし知っている方がいましたら、教えてください。

あるファイルを読み込み、その1行ずつに対し処理を行ないたい場合があったとします。

   例えば、ファイル内に、下記のようなデータがあって、左側の値を変数名として、
   配列(String)に格納し、右側の値を数値として、配列(Integer)に格納していくと
   いった場合。

                aaa 123
                bbb 4567
                ccc 888888
                     :
                  以下続く

このような処理を行なうために、最初は、ReadLine を用いて処理していましたが、
ファイルが大規模になる場合、あまりにも時間がかかってしまいます。

そこで、以前ネットニュースで知った方法ですが、一旦バイナリで読み込んでから
処理しようと思い、プログラムを変更しようとしたのですが、読み込んだ文字列
(ファイルの内容全て)から、1行ずつ取り出す処理がわかりません。 InStr で vbLf 
を検索して抜きだしたりもしましたが、時間の解決にはなっていません。

読み込むまでの処理は、下記のように組みました。全体の読み込み自体は、ReadLine
を用いるより、かなり早くなりました。このstrから、1行ずつ抜きだしたいと思っ
ています。
−−−−−−−−−−−−−−−−−−−−−−−−−−−
Dim f_num As Integer
Dim i_file As String
Dim str As String

f_num = FreeFile
Open i_file For Binary Access Read As #f_num
str = StrConv(InputB(LOF(f_num) - 1, #f_num), vbUnicode)
Close #f_num
−−−−−−−−−−−−−−−−−−−−−−−−−−−

i_file は、UNIX(Solaris)上で作成されたファイルで、改行コードが vbLf しかありません。そのため 
Line Input# では、1行と判断してくれず、ReadLine を用いていました。

よろしくお願いします。
#2737-1
RE#2720:高速なファイルからの読み込み(1行ずつ)法
VBの制限があるので、あんまり大きいファイルだと扱えないのですが…。 とりあえず作ってみます。

Private Sub Command1_Click()
    Dim cDim(10000) As String 'テキトーに大きい行数
    Dim cw As String * 32767  '扱うファイルサイズより大きい数
    Dim lSt As Long
    Dim lEd As Long
    Dim lEdMax As Long
    Dim lMax As Long
    Dim l As Long

'*** オリジナルを一気読み ***
    Open "c:\aaa" For Binary Access Read As #1
    Get #1, , cw
    Close #1

'*** 配列に分割格納 ***
    lMax = 0
    lSt = 1
    lEdMax = InStr(cw, vbNullChar)
    lEd = InStr(cw, vbLf)

    While lEd
        cDim(lMax) = Mid(cw, lSt, lEd - lSt)
        lSt = lEd + 1
        lEd = InStr(lSt, cw, vbLf)
        lMax = lMax + 1
    Wend

'*** 最後の1行 ***
    If lEdMax - lSt Then
        cDim(lMax) = Mid(cw, lSt, lEdMax - lSt)
        lMax = lMax + 1
    End If

'*** WIN形式で保存 ***
    Open "c:\bbb" For Output As #1
    For l = 0 To lMax - 1
        Print #1, cDim(l)
    Next l
    Close #1
End Sub

速いかどうかは、あんまり判りません。(多分、読みは速いとは思う…)

とにかく、ディスクのI/Oにかかる時間が遅いだろうから、I/Oする回数を減らす事を考えれば
良いかと思いますよ。 ドでかいファイルを扱うのなら、適当なブロック単位で部分読みして、その
中に Lf があるかという処理で何とかいけると思います。
#2758-1
RE#2737:高速なファイルからの読み込み(1行ずつ)法
せつらさん、ありがとうございます。

>     Dim cw As String * 32767  '扱うファイルサイズより大きい数

このファイルサイズが特定できないので、読み込み方は、質問のようににして、
下記の1行ずつの処理方法を使用させていただきます。m(-_-)m

> '*** 配列に分割格納 ***
>     lMax = 0
>     lSt = 1
>     lEdMax = InStr(cw, vbNullChar)
>     lEd = InStr(cw, vbLf)
> 
>     While lEd
>         cDim(lMax) = Mid(cw, lSt, lEd - lSt)
>         lSt = lEd + 1
>         lEd = InStr(lSt, cw, vbLf)
>         lMax = lMax + 1
>     Wend

> 速いかどうかは、あんまり判りません。(多分、読みは速いとは思う…)

今までの処理方法に比べたら、格段に早くなりました。Splitを使用する方法も
試したのですが、これでもかなり遅くて、VBで開発するのやめようかと思っていました(-_-;

当方の環境を書いていませんでしたが、WinNT4.0SP5/VB6.0SP3で開発しています。
同様の処理を、UNIXのC/OPENLOOKで組んでいたのですが、この場合の処理時間に比べ、
数十倍の時間を必要としています。現在でも数倍時間はかかりますが、
待てない時間ではなくなってきました。
読み込ませているファイルは、1行10文字程度で、120MByte程度あります。
しかも、これが最大というわけではありません(ToT)

ありがとうございました。もし、これ以上の方法等があれば、引き続きご教授願います。
また、今後も壁にぶち当たりましたら、質問したいと思いますので、
その時はよろしくお願いします。
このページと関連する記事:
#5249-1改行コードが 0x0A のテキスト形式ファイルの読み込み1999-09-16(木) 11:41
#46642-0ファイルの行数カウント2001-09-07(金) 11:56
#21351-0読み出しの時間2001-06-14(木) 07:00
#29794-0テキストエディタの速度2000-09-12(火) 09:20
#10424-0ファイルの中身を置換する方法1999-11-26(金) 11:28
#16318-0配列について2001-05-25(金) 22:57
#35716-0動的配列について2000-12-20(水) 15:19
#4628-0RE#4625:line input ステートメントでの読みこみ1999-12-28(火) 02:46
#508-3テキストファイルを一気に読み込みたい。2003-12-05(金) 20:54
#30994-0テキスト読込みを速くするには2000-10-03(火) 09:39
お探しの情報は見つかりましたか?お困りの問題は解決しましたか?
サイト内検索, 似た記事検索で見つからなくてもあきらめずに掲示板で質問してみましょう。
VB初心者友の会があなたのお役に立てれば幸いです。また、本ページの投稿者の方々にこの場を借りて感謝致します。
本ページは過去ログを集めて自動構成しています。よろしければこのページに関するフィードバックをお願いします。
(※ 構成の誤り、広告等の不適切な記事、リンク切れ、読めないページの報告など)