この人頭いいなと思ったエピソード

はじめまして。
初投稿の新米プログラマです。

VB6.0で多種類のファイルをバイナリデータとして読み込んで
返却する関数を作成しています。

'-------------------------------------
' ファイルからバイナリデータを読み込む
'-------------------------------------
private Function GetBinaryData(ByVal strFileName As String) As Byte()
On Error GoTo Exception

Dim fileNo As Integer
Dim fileSize As Long
Dim bytData() As Byte

'ファイルのサイズを取得する
fileSize = FileLen(strFileName)
ReDim bytData(fileSize - 1)

'バイナリデータ読み込み
fileNo = FreeFile
Open strFileName For Binary Access Read As fileNo
Get #fileNo, , bytData
Close #fileNo

'戻り値の設定
GetBinaryData = bytData
Exit Function

'エラー処理
Exception:
MsgBox (CStr(Err.Number) & " " & Err.Description)

End Function

ですが、↑の関数にサイズの大きなファイル(100M程度)を指定したとき
 ReDim bytData(fileSize)
で、「メモリが不足しています」というエラーが発生してしまいます。

発生の仕方としては、'エラー処理のMsgBoxで表示されることも
ありますし、プログラムが停止することもありますし、
On Error GoToを記述しているのにも関わらず
VBのメッセージボックスが表示されることもあります。
 #[継続][終了][デバッグ][ヘルプ]のボタンが出ているやつです。

ちなみに、50M程度のファイルであれば読み込めています。

このエラーが発生する原因は何なのでしょうか?
また、解決方法(サイズの大きなファイルを確実に読み込む方法)は
あるのでしょうか?
解決方法がないのであれば、「○M以上のファイルはエラー」という
仕様にしようと思うのですが、
何Mまでなら確実に読み込むことが出来るのでしょうか?

…もしくは上のコーディング自体、検討違いでしょうか^^;
 #バイト配列の要素数に上限があるとか…?

とても困っています…
どうかよろしくお願い致します。

A 回答 (1件)

実行環境に依存するようにも思えます



当方で単に確保するのみの確認したところでは ReDimで340MB程度は確保できるようでした
関数が配列を返す場合一時的に内部で使用しているローカル変数と呼び出し元の受け手の配列の2つ領域で同じ大きさの配列が必要になると思われます

ファイルの読み込みを 1度にしないといけないのでしょうか
50MB程度のバッファを用意して読み込み、必要な処理を行い
次ブロックを読み込んで、必要な処理
といったループを組めば済むように感じます

終端処理のため処理したByte数の管理は必要でしょうが …
LOF関数やLOC関数などを使って残りがいくつあるかは確認可能です
    • good
    • 0
この回答へのお礼

回答ありがとうございました!

こちらでも調べてみたところ、どうやら配列を宣言するとき
メモリに配列の要素数分の「連続したエリア」がないと「メモリ不足」になるらしい、です。
http://chaichan.web.infoseek.co.jp/vbtips/VBMemo …
断片化したメモリをかき集めて作ってはくれないのですね…。
なので
>実行環境に依存するようにも思えます
というのは、おっしゃる通りでした。

>ファイルの読み込みを 1度にしないといけないのでしょうか
ファイルの読み込み自体を一度にする必要はないのですが、
最終的に1つのバイト配列に格納しなければいけないのです…。

結局、「最終的に1つのバイト配列に格納しなければいけない」という状況から
「サイズの大きなファイルを確実に読み込む方法」は「無理!」という結論に至りました。
その状況がなければredfox63さまの回答の通りだったと思います。
ありがとうございましたm(_ _)m

お礼日時:2008/06/19 22:55

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報