UWSCでバイナリーファイルの読み書き
ADODB.Streamを使えば、バイナリーファイルの読み書きももちろん可能。
バイナリーが使えない、という記述を見たのでやってみた。
メイン部分に書いた、テスト用スクリプトで使い方は分かるでしょうけど、
読み書きは1オクテット単位(0〜255)でしか考えていません。
あと、Binary.Initの引数で、同時に扱うファイル数が指定できます。
初期値は、32。否、33だった。
-1とか指定する人は知りません。
スレッドで多重アクセスも知ったことではありません。
どちらもチェックを追加すれば良い話ではありますが。
Binary.uws
OPTION EXPLICIT IFB GET_UWSC_NAME = "Binary.uws" THEN WITH Binary DIM path = "Binary.test.dat" // 書き込み DIM h = .Open(path), i IFB h <> .INVALID_HANDLE THEN // 単体書き込み FOR i = 255 TO 0 STEP -1 .Write(h, i) NEXT // 配列書き込み DIM add[] = 13, 10, 48 .WriteArray(h, add) // 最後のバイトを上書き .Position(h, -1) .Write(h, 49) ENDIF .Close(h, TRUE) // 読み込み h = .Open(path) IFB h <> .INVALID_HANDLE AND .Exist(h) THEN WHILE !.EOS(h) PRINT .Position(h) + ": " + .Read(h) WEND // 後ろ3バイトカットしてみる .Position(h, -3) .EOS(h, TRUE) ENDIF .Close(h, TRUE) // 読み込み一括 h = .Open(path) IFB h <> .INVALID_HANDLE AND .Exist(h) THEN DIM read = .ReadArray(h), m = .Size(h) - 1 .Close(h) // 既に読み込み済みなのでClose可 FOR i = 0 TO m PRINT read[i] NEXT ENDIF .Close(h) // 二回Closeしても、問題はない ENDWITH ENDIF MODULE Binary CONST MAX = 32 CONST BINARY = 1 CONST TEXT = 2 CONST INVALID_HANDLE = -1 CONST ALL = -1 CONST LINE = -2 CONST CREATENEW = 1 CONST OVERWRITE = 2 DIM _max = MAX DIM _adodb[MAX] DIM _box[MAX] DIM _path[MAX] DIM _exist[MAX] PROCEDURE Binary() Init() FEND PROCEDURE Init(m=MAX) RESIZE(_adodb, m) RESIZE(_box, m) RESIZE(_path, m) RESIZE(_exist, m) // ADODB.Streamを作成し、書き込み用・バリアント配列の箱を確保する _adodb[0] = CREATEOLEOBJ("ADODB.Stream") WITH _adodb[0] .Open() .Type = TEXT .WriteText(CHR(0)) .Position = 0 .Type = BINARY _box[0] = .Read(1) .Close() ENDWITH _adodb[0] = NULL _path[0] = EMPTY _exist[0] = FALSE DIM i FOR i = 1 TO m _adodb[i] = NULL _box[i] = _box[0] _path[i] = EMPTY _exist[i] = FALSE NEXT _max = m FEND FUNCTION Open(path) RESULT = INVALID_HANDLE DIM i FOR i = 0 TO _max IF _adodb[i] = NULL THEN BREAK NEXT IFB i <= _max THEN _adodb[i] = CREATEOLEOBJ("ADODB.Stream") WITH _adodb[i] .Open() .Type = BINARY TRY _adodb[i].LoadFromFile(path) _exist[i] = TRUE EXCEPT // ファイルがなくても良いじゃない _exist[i] = FALSE ENDTRY ENDWITH _path[i] = path RESULT = i ENDIF FEND FUNCTION Read(i) DIM read = ReadArray(i, 1) RESULT = read[0] FEND FUNCTION ReadArray(i, num=ALL) RESULT = _adodb[i].Read(num) FEND FUNCTION Write(i, bData) RESULT = FALSE IFB bData >= 0 AND bData < 256 THEN DIM box = _box[i] box[0] = bData _adodb[i].Write(box) RESULT = TRUE ENDIF FEND FUNCTION WriteArray(i, bData[],s=0,e=-1) RESULT = TRUE DIM j, m = e IF e = -1 THEN m = RESIZE(bData) FOR j = s TO m RESULT = RESULT AND Write(i, bData[j]) NEXT FEND FUNCTION Save(i, o=OVERWRITE) TRY _adodb[i].SaveToFile(_path[i], o) RESULT = TRUE EXCEPT RESULT = FALSE ENDTRY FEND FUNCTION Close(i, bSave=FALSE) RESULT = FALSE IFB _adodb[i] <> NULL THEN IF bSave THEN Save(i) _adodb[i].Close() ENDIF _adodb[i] = NULL _path[i] = EMPTY _exist[i] = FALSE RESULT = TRUE FEND FUNCTION CopyTo(i, j, num = ALL) RESULT = FALSE _adodb[i].CopyTo(_adodb[j], num) RESULT = TRUE FEND FUNCTION EOS(i, set=FALSE) IF set THEN _adodb[i].SetEOS() RESULT = _adodb[i].EOS FEND FUNCTION Size(i, val=ALL) IF val > ALL THEN _adodb[i].Size = val RESULT = _adodb[i].Size FEND FUNCTION State(i) RESULT = _adodb[i].State FEND FUNCTION Position(i, pos=NULL) IFB pos <> NULL THEN IF pos < 0 THEN pos = pos + _adodb[i].Size _adodb[i].Position = pos ENDIF RESULT = _adodb[i].Position FEND FUNCTION Exist(i) RESULT = _exist[i] FEND ENDMODULE