容量の大きいビットマップファイルからバイナリデータを取得するには?


初心者.NET  2005-12-19 19:51:14  No: 129044

こんばんわ。お世話になります。

ビットマップファイル(フォント)をバイナリデータで取得させる処理を書いております。
そこで、こちらを検索してみたら「π様」と「魔界の仮面弁士様」のスレッドを見て、処理を書きました。
しかし、容量が小さいファイルだとすぐにバイナリデータを取得できるのですが。。。容量が大きいファイル(現在の容量10M)をバイナリデータで取得しようとすると、アプリがフリーズしてしまい処理ができなくなってしまいます。
ちなみに、使用させていただいた処理は↓
=======================
Dim FilePath As String = "C:\TEST.TXT"
Dim DataFile As New System.IO.FileInfo(FilePath)
If DataFile.Exists AndAlso DataFile.Length > 0 Then
    With New System.IO.BinaryReader(DataFile.OpenRead())
        Me.TextBox1.Text = BitConverter.ToString(.ReadBytes(CInt(DataFile.Length)))
        .Close()
    End With
Else
    Me.TextBox1.Clear()
End If
=======================
こちらです。

この処理で容量の大きいファイルを読み込ませると、
=======================
Me.TextBox1.Text = BitConverter.ToString(.ReadBytes(CInt(DataFile.Length)))
=======================
ここの処理で止まってしまうことが判明しています。
=======================
Dim Buffer() As Byte
=======================
を使用してもフリーズしてしまいます。

どなたかご教授願います!よろしくお願い致します。


ガッ  2005-12-20 00:23:21  No: 129045

なぜBitConverterに10MBのバイナリを突っ込んでいるのかが分からないので、
これ以上どうこうできませんねぇ。


メモリ的には、
1  ファイルから読み取った10MB=1024*1024*10(Byte)のデータ
2  1バイトがUnicodeで"xx-"(終端は"xx"だけど、それを無視して)となるので、
    3*sizeof(System.Char)*1024*1024*10(Byte)
    のデータ
が作られます。
なので、まぁsizeof(System.Char)が4だとすれば、136314880(Byte)でつまり、
130MBくらいになりましょうか。

コレだけのメモリ確保と、10進表記への変換が重なれば大抵のコンピュータにはかなりの負荷となるのではないでしょうか?
※計算あってるかなぁ…


Dental  2005-12-20 09:40:05  No: 129046

> Me.TextBox1.Text = BitConverter.ToString(.ReadBytes(CInt(DataFile.Length)))
> =======================
> ここの処理で止まってしまうことが判明しています。

もう少し切り分けましょう。

BinaryReader.ReadBytes に時間がかかっているのか?
BitConverter.ToString に時間がかかっているのか?
TextBox.Text への代入に時間がかかっているのか?
それぞれ、どの程度の時間がかかっていて、それをどこまで短縮したいのか?


> なので、まぁsizeof(System.Char)が4だとすれば、
SDK上では、Char 構造体は「16 ビットの数値として実装されています。」と
書かれているんですけどね……。Charは2バイトです。

> 130MBくらいになりましょうか。
ならんでしょう。単純計算でも 60MB 程度かと。
3 * (10MB * Charサイズ) なら、「30MB × Charサイズ」ですからね。

仮にCharサイズが4バイト換算だったとしても、120MB にしかならないと思いますが。


ガッ  2005-12-20 10:55:36  No: 129047

> SDK上では、Char 構造体は「16 ビットの数値として実装されています。」と
.NETになって異様に増えたなーくらいにしか捉えてなかったんで、勝手に4バイトだと考えました(orz

> 仮にCharサイズが4バイト換算だったとしても、120MB にしかならないと思いますが。
これはファイルから読み込んだ10MBも換算に入れて計算した結果です。


何にしろ、出題者が
> ビットマップファイル(フォント)をバイナリデータで取得させる処理
と言っているのに、何故BitConverterで全て変換して文字列として処理させようとしているのかが分からない限り、
何ともいえませんね。


初心者.NET  2005-12-20 11:54:27  No: 129048

ガッ様、Dental様、ご回答ありがとうございます。そして返事遅れて申し訳ないです(><;

>なぜBitConverterに10MBのバイナリを突っ込んでいるのかが分からない
説明不足でした。。。
ビットマップファイル(というかフォント)の容量が10Mあるのですが、このビットマップを一括してデータを取得したいのです。
ビットマップファイルに1文字ずつ文字が埋め込まれているのですが、1文字ずつ処理しようとすると、1文字を切り取ってそれぞれのデータを取得しようとすると、約10000文字あるので、切り取りにかなりの時間がかかってしまいます。
そこで、一括してデータを取得できるようにすれば時間をかけずにできると思ったからです。
・・・おわかりになられたでしょうか。(^^;


> BinaryReader.ReadBytes に時間がかかっているのか?
> BitConverter.ToString に時間がかかっているのか?
> TextBox.Text への代入に時間がかかっているのか?
> それぞれ、どの程度の時間がかかっていて、それをどこまで短縮したいのか?
調査したところ、TextBoxに代入するときに時間がかかっているようです。やはりデータが大きすぎるからなのでしょうかね。。。

一応、一気に120KBまで落としてやってみましたが、上記の部分で約2分ほどかかっていました。220KBだと、約6分かかっていました。。。
ちなみに、バイナリエディタ[Stirling]というものを使用させていただいて、10Mのファイルを処理してみたところ、1秒くらいで全てのデータ取得できました(^^;
ここまで速く!とは言いませんが(むしろできない?)まぁせめて1分〜2分弱ぐらいでデータを取得したいと考えております。。。

何かいい方法はありますでしょうか。。。私なりにも考えてみます。


初心者.NET  2005-12-20 11:58:40  No: 129049

>何故BitConverterで全て変換して文字列として処理させようとしているのかが分からない限り、
>何ともいえませんね。
そういうことですかorz
とりあえず結果が出ればいい!と思っていたので、、、(^^;

何か違う方法があるのでしょうか?


Dental  2005-12-20 12:13:16  No: 129050

いや、Stirling は、全データを表示させているわけじゃ無いのでは?
スクロールの可視領域(+α)に見えている部分を表示させているだけだと思う。


初心者.NET  2005-12-20 12:57:12  No: 129051

> Stirling は、全データを表示させているわけじゃ無いのでは?
え・・・そうなんですか?
かなりのデータ量が表示されたので、全て表示させているのかと思っていました。。。orz  そういうところも、まだまだ未熟です(^^;


初心者.NET  2005-12-20 16:00:09  No: 129052

> 何故BitConverterで全て変換して文字列として処理させようとしているのかが分からない限り、
> 何ともいえませんね。
本当に申し訳ないです。。。
16進数でダンプしたいということです。自分の中ではわかっていたのでは、
ご回答くださる方は全くわからないですよね(^^;
本当にすみませんでした。


※作成する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。







   このエントリーをはてなブックマークに追加