バイナリファイルの書き込み

解決


出る牌  2010-11-01 01:03:08  No: 39461

お世話になります。  D6P + XP
バイナリファイルを書き込む部分をVBからDELPHIに移植を試みています。目的とするサンプルを探しましたが手がかりがつかめず質問させていただきました。Delphiのページで恐縮ですがやりたいことはVBで書くと次のようなものです。

'Private VLng(200) As Long 'VBでは4バイトの整数
'Private Vsgl(200) As Single '4バイト
'Private Ndata As Integer

Private Sub Command1_Click()
Dim BinFile As String
Dim P0 As Integer, I As Integer, II As Integer

BinFile = App.Path & "\TEST1.bin"
Open BinFile For Binary As #1

For I = 1 To NData
    P0 = (I - 1) * 8 + 1
    II = P0     : Put #1, II, VLng(I)    
    II = P0 + 4 : Put #1, II, Vsgl(I) 
Next I

Close #1
End Sub

よろしくお願いします。


igy  2010-11-01 04:18:07  No: 39462

>目的とするサンプルを探しましたが手がかりがつかめず質問させていただきました。

Googleなどで、
  Delphi バイナリファイル
で検索すると、参考になるページとかありませんか?

たとえば、
はじめてのDelphi(その6−2)
http://www.osk.3web.ne.jp/~satou/delphi6b.htm
とか。


出る牌  2010-11-01 22:00:30  No: 39463

igy様  ありがとうございました。
紹介してくださったサイト(はじめてのDelphi(その6−2))は以前にも拝見しました。ここには構造体?とかが出てきてSizeOfなどがわからずにパスしてしまいましたが今回は原理もわからないままに試行錯誤した結果次のようなもので一応目的のデータができ、読み取りテストでも成功しました。

procedure binwt(bfile:string);
var
i:integer;
sbf:file;
begin
    AssignFile( sbf, bfile );
    Rewrite( sbf, 4 );        //  *1
    for i := 1 to ndat do begin
        BlockWrite( sbf, VLng[i], 1 );  //  *2
        BlockWrite( sbf, VSgl[i], 1 );
    end;
    CloseFile( sbf );
end;

*1はSizeOfというところに4を入れてみました。これは1レコードあたりのサイズと解釈しましたがよろしいでしょうか?
*2のところの1はサンプルのままとしましたがこの意味は何でしょうか?
結果はオーライのようですが自信がもてません。問題点、パラメーターの意味などをご指導くださるようよろしくお願いします。


TS  2010-11-02 01:00:47  No: 39464

意味も分からずにプログラムを組めば間違いが多発します。
まず、ヘルプを見ましょう。
コードのBlockWriteの先頭にカーソルを移動して。F1のキー
を押して見て下さい。BlockWriteのヘルプが出ます。
ここに詳しく書いてあります。


出る牌  2010-11-02 03:18:51  No: 39465

TS様  アドバイスをありがとうございます。
関連するHELPを見て例なども見ていましたがまったくの独学のためどうもその解説の個々の単語の意味するところに自信が持てずお聞きしたものです。一般的にHELPの例なども他の多くの知識があることを前提としたひねったものが多いようで苦戦します。とりあえず動くようになりましたのでしばらくこれでテストしてみます。
助かりました。


TS  2010-11-02 06:08:12  No: 39466

失礼しました。
>単語の意味するところに自信が持てずお聞きしたものです。
私も自信は無いですが。

>Rewrite( sbf, 4 );        //  *1
4と言う数字はファイルを書き出すときの一度で書き出すサイズ
4の代わりにSezeOf(integer)としても同様の結果が出ます。

>BlockWrite( sbf, VLng[i], 1 );  //  *2
sbfのファイルにVLng[i]を上記のサイズ分で1個だけ書き出しなさい。

よって数字の4と1を入れ替えても同様に動作すると思います。

Rewrite( sbf, 1 );  として置いて
BlockWrite( sbf, VLng[i], SezeOf(integer) );
とか独自のSezeOf(T適当な型)とかの書き出しができます。

type TMyTest=Record
       VLng: array [0..200] of integer;
       Vsgl: array [0..200] of shortInt;
     end;
Var MyTest:TMyTest;
とするとSezeOf(TMyTest)でそのデータのサイズを指定すると
MyTestのデータが一度で書き出されます。

と言う説明はヘルプより余計に分からなくしてしまうでしょうか。


出る牌  2010-11-02 19:19:20  No: 39467

TS様  ご親切なお返事をありがとうございました。
今回の件で同じコードをずっと眺めていて何となく意味を推察してもしやSizeOfは実数値を入れてもできるのでは?  などと出力結果をバイナリエディタで確認しながら試行錯誤してきました。お蔭様でこれで確信が持てるようになりました。また構造体?とはこのように使える、というヒントをいただきましたのでワンランク上がった気がします。Delphiは独学するには難解なところが多くありますがそれにも増して動作速度やランタイムからの開放など多くの魅力がありますので少しづつ勉強したいと思います。ありがとうございました。


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

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






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