ファイルのロードとセーブ
ファイルの読み込みについては、既に行ったことがあります。
picload命令による画像読み込みですが、覚えていますか?
この章では、様々なファイルデータを変数に読み込む方法と、書き出す方法を紹介します。
制限はほとんどなく、あらゆるファイル形式を読み書き出来ますが、説明ではテキストデータのみを扱います。
バイナリデータを操作する場合、NULLの判定に注意してください。
まずは、変数の内容をファイルに書き出す命令から説明します。
| bsave ファイルパス, 保存変数, 保存サイズ, オフセット |
| | | |
| ファイルパス | 保存するファイルのパスを指定する。 |
| 保存変数 | ファイルに書き出す文字列を入れた変数を指定する。 |
| 保存サイズ | 書き出すサイズを指定する。(※指定しなければ変数サイズ) |
| オフセット | 書き出すファイルに追記する場合、オフセットを指定する。 |
名前の由来は恐らく、BinarySAVEの略でしょう。
第1パラメータのファイルパスは、絶対・相対パスのどちらでも可能です。
保存するデータを一式入れた変数を第2パラメータの保存変数に指定して、
保存サイズを、第3パラメータにバイト単位で指定してください。
省略または−1を指定すると、変数サイズ分がそのまま書き出されます。
このbsave命令はバイナリ操作命令なので、テキスト処理命令のようにNULLまでではありません。
つまり例えば、テキストデータとして保存したい場合に、テキストサイズが40であったとすると、
変数は初期サイズで64なので、24バイト分はNULLデータで埋められることとなります。
下記サンプルのように、strlen関数で保存サイズを指定するようにしましょう。
第4のオフセットパラメータは、書き出すファイルを完全に上書きするのではなく、
追記(オフセット以降は上書き)する場合に使用します。
例えば複数の変数値を、変数の連結でbsave命令実行するのではなく、
一つ目の変数値を書き出した後、2つ目の変数値も書き出す場合や、
元々のファイルサイズが非常に大きく、そのファイルの一部分を更新する場合等です。
オフセットを省略するか、−1(厳密にはマイナス値)を指定すると、
既にファイルが存在しようとしまいと完全に変数値の内容だけのファイルが出来上がります。
−1以外を指定するとき、もしファイルが存在しなければエラーとなります。
存在する場合、指定したオフセット以降のファイル内容は変数値で上書きされます。
sdim buf, 1000
objsize 640, 25
mesbox buf, , 455, 5
button "上記の内容を保存する", *save
stop
*save
dialog "txt", 17, "保存先"
if stat : bsave refstr, buf, strlen(buf) // テキストサイズ分だけ保存
|
サンプルではtxt形式で保存しましたが、ini形式やその他どんな形式であろうとも、
拡張子と内容の一致はプログラム側が対応することであって、
特定の拡張子を指定したから内容がその特定の形式で保存されるわけではないのです。
ある一定のルールを決めさえすれば、自分独自の新しい形式・拡張子で保存して構いません。
保存とは逆の処理、変数への読み込みを行います。
メモ帳などのテキストエディタだと、一からデータを作成する場合には必要ありませんが、
既存のファイルを編集する場合であったり、
ソフトの設定データであれば、起動初期時に前回の設定を自動で反映させることができます。
| bload ファイルパス, 読込先変数, 読込サイズ, オフセット |
| | | |
| ファイルパス | 読み込み元のファイルパスを指定する。 |
| 読込先変数 | ファイル内容の代入先変数を指定する。 |
| 読込サイズ | 読み込むサイズを指定する。(※指定しなければ変数サイズ) |
| オフセット | 先頭以外から読み込む場合に指定する。 |
bsave命令と同じく、名前の由来はBinaryLOADの略でしょう。
パラメータの指定もbsave命令とほとんど同じ内容となっています。
第1パラメータにパス名、第2パラメータは変数、第3にサイズ、第4にオフセット。
変わるのは、保存が読み込みに変わるというだけです。
大きなファイルの一部を読み込むときはオフセットパラメータを指定します。
−1(マイナス値)の指定もできますが、bsave命令と異なり変数領域への上書きとなるため、
−1と0、どちらを指定しても最初から指定サイズ分を読み込みます。
読込先の変数に読み込むファイル以上の何らかのデータが既に入っている場合、
既存の内容と読み込む内容に区切りが出来ないため、混ざってわからなくなってしまいます。
bload命令で読み込むと、読み込んだ総バイト数がシステム変数strsizeにセットされますので、
その位置を基準にNULLをセットしたり、変数サイズを再セットしたりして対応してください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
sdim buf, 256
objsize 320, 25
mesbox buf, 640, 455, 5
button "読み込む", *load
pos 320, 455 : button "保存する", *save
stop
*load
dialog "txt", 16, "読込元"
if stat {
buf = "" // ゴミが残るのを防ぐ
bload refstr, buf // 変数に読み込む
title "読み込んだサイズ:" + strsize
objprm 0, buf
}
stop
*save
dialog "txt", 17, "保存先"
if stat : bsave refstr, buf, strlen(buf)
|
サンプルで、もし存在しないファイル名を読み込み元ファイルに指定してしまったら、
プログラムエラーとなって強制終了してしまいます。
また、変数サイズ以上のサイズをパラメータに指定しても変数は自動拡張してくれません。
予め読み込む前にファイルの有無やサイズを知っておくには次の命令を使いましょう。
この章の最後に紹介するのは、ファイルサイズを取得する命令です。
| exist ファイルパス |
| | | |
| ファイルパス | 調査するファイルのパスを指定する。 |
関数にできただろうになぜか命令のまま、という疑問はさておき、
パラメータにサイズを調べるファイルパスを指定することで、strsizeにファイルサイズがセットされます。
ファイルが存在しない場合は−1が返りますので、ファイルのサイズ取得用に利用するというよりも、
ファイルが存在するかどうかのファイルチェック用に利用する機会の方が多いかもしれません。
それでは、このexist命令を使って、先程のサンプルを書き換えてみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
sdim buf, 256
objsize 320, 25
mesbox buf, 640, 455, 5
button "読み込む", *load
pos 320, 455 : button "保存する", *save
stop
*load
dialog "txt", 16, "読込元"
if stat {
exist refstr // ファイルサイズをチェックする
if strsize = -1 : stop // 指定ファイルがなかったら処理中断
sdim buf, strsize
bload refstr, buf
title "読み込んだサイズ:" + strsize
objprm 0, buf
}
stop
*save
dialog "txt", 17, "保存先"
if stat : bsave refstr, buf, strlen(buf)
|
HSP2では、文字列型配列変数をbsave命令で一括保存することが出来ましたが、
HSP3以降は、変数サイズが自動で変わるようになり、メモリの確保方法が変わったので、
配列の一括保存ができなくなりました。
配列丸ごと保存する場合は、下記のようにプログラム側で対応するようにしましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
num = 5 // ボックス数
file = "sample.hbc" // Hot-soup-processorBeginner'sClubオリジナル形式
sdim data, 256, num
objsize 320, 20
pos 0, 0 : button "Load", *l
pos 320, 0 : button "Save", *s
pos 0
repeat num
mesbox data.cnt, 640, 460 / num
loop
stop
*l
exist file
if strsize ! -1 {
repeat num
bload file, data.cnt, , cnt * 256
objprm cnt + 2, data.cnt // 各ボックスに入れていく
loop
}
stop
*s
repeat num
bsave file, data.cnt, , (cnt = 0) * -1 + cnt * 256 // 1つのファイルに足していく
loop
dialog "保存しました。"
|
上記、最後のサンプルは特殊な使い方の為に使えませんが、
それ以外のサンプルは単純なテキスト形式の読み書きだけなので、
bload、bsave命令を使うよりも次章で説明するテキスト形式に特化した命令を使う方が簡単で安全です。
尚、何度も書くようにバイナリ操作命令のため、
これらの命令でテキスト形式の読み書きを行う場合、自分で変数を適した形にするようにしてください。
もし、数値の「65」を保存しようとしていても、
数値型の「65」はバイナリ処理ではASCIIコードの「A」を指定したと誤認され、「A」と保存されます。
また、読み込む場合も数値型変数のままだと、型変換は行われずに意図しない数値が読み込まれます。
重要なポイントの1つなので覚えておきましょう。