Perl から Lua :バイナリファイルの入力

2016-12-18 :  PCクリニック
Python、C言語、Perl、化学業界、硝子業界、グルコサミン、Firefox
前(2016-12-16)の記事「Perl から Lua :ディレクトリ内ファイル一覧」に続いて、

かれこれ4年ほど前に、“Perl”で書いていたものを、

Lua”と云っても、“GSL Shell
に移植するための
気になる幾つかの処理部分を整理した。

今回が3つ目。これで最後?

バイナリファイルの入力について。

読み込みたいファイルは、C言語で書き出したもの。
つまり、4バイトintegerデータ配列そのまま。

当時の Perl では:
# ・・・・・
# ・・・・・
open ( IN, $IT ); binmode IN;
read ( IN, $w, $k*4);
for ( $j=0; $j<$k; $j++ ){
$bd = substr($w,$j*4,4); $c= unpack( "l", $bd );
# ・・・・・
# $c の配列を作る
# ・・・・・
}
close( IN );
# ・・・・・
# ・・・・・
の様にコーディングしていた。
ここで、
$IT(ファイル名)、$k(配列要素数)は、事前に定義済み。


この部分を、Lua では、どの様に書く???

バイナリファイルの入力については、
Lua 学習初め頃(2016-01-25)の記事「Lua 学習:LFS ( LuaFileSystem )
において、
  ・・・・・
  ・・・・・
  上記処理で、ファイルのサイズが取得できたら、
  (Lua基本には無い?)バイナリでのファイル読み込みができる。
local lfs = require'lfs'
Fname = 'test.dat' -- テスト用
SZ = lfs.attributes( Fname, 'size' ) -- ファイルサイズ

-- +++++ 以下は、FFI と C Library Function で。
local ffi = require'ffi'
ffi.cdef[[
void* fopen( const char* fname, const char* type );
int fread ( void* buf, int size, int count, void* fp );
int fclose( void* fp );
]]
fnm = ffi.new( 'uint8_t[?]', #Fname )
buf = ffi.new( 'uint8_t[?]', SZ )

fnm = Fname -- この代入(型変換?)、必須。
IN = ffi.C.fopen( fnm, 'rb' )
fsize = ffi.C.fread( buf, 1, SZ, IN )
print( string.char( buf[SZ-1] ) ) -- 確認:ファイル丸ごと読めている!
rtnCD = ffi.C.fclose( IN )
  出来た!
  ・・・・・
  ・・・・・
と書いている。
この処理方式を流用すれば行ける。


と云うことで、

Lua では、以下:
-- ・・・・・
-- ・・・・・
SZ = k*4 ----- ファイルサイズ
ffi.cdef[[
void* fopen( const char* fname, const char* type );
int fread ( void* buf, int size, int count, void* fp );
int fclose( void* fp );
]]
buf = ffi.new( 'int32_t[?]', k )
IN = ffi.C.fopen( 'IT', 'rb' )
fsize = ffi.C.fread( buf, 1, SZ, IN )
-- ・・・・・
-- buf が、上記 Perl での、$c の配列に相当。
-- ・・・・・
rtnCD = ffi.C.fclose( IN )
-- ・・・・・
と云うことですネ。
つまり、実質1行?
でも、なんだか行数が多い?


今少し学習したら、ffi.C でなくても行ける!

つまり、以下の改訂コード:
-- ・・・・・
-- ・・・・・
SZ = k*4 ----- ファイルサイズ
buf = ffi.new( 'int32_t[?]', k )
IN = io.open( 'IT', 'rb' )
bbb = IN:read( '*a' ); ffi.copy( buf, bbb, SZ )
-- ・・・・・
-- buf が、上記 Perl での、$c の配列に相当。
-- ・・・・・
IN:close( )
の様に、LuaだけでOKだった。


更に、ffi.copy は無くせないのか???


無くても良かった。

再改訂(決定版)コード:
-- ・・・・・
-- ・・・・・
SZ = k*4 ----- ファイルサイズ
IN = io.open( 'IT', 'rb' )
bbb = IN:read( '*a' )
buf = ffi.cast( 'int32_t*', bbb )
-- ・・・・・
-- buf が、上記 Perl での、$c の配列に相当。
-- ・・・・・
IN:close( )
これで十分だった。


本日はここまで。


“Perl から Lua ( GSL Shell ) への移植”準備は終了?


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


161129
関連記事
スポンサーサイト

コメントの投稿

管理者にだけ表示を許可する

おきてがみ/blogram
blogram投票ボタン



おきてがみ

最新記事
カレンダー
05 | 2017/06 | 07
- - - - 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 28 29 30 -
月別アーカイブ
カテゴリ
最新コメント
検索フォーム
リンク
プロフィール

<紙>

Author:<紙>
ようこそ。
「パソコンヲタクの雑記帳」
もろもろなことを綴っています。
パソコン ヲタクってねくら?
画像は kami でなく kani です。

カウンター(fc2、i2i) /Google Analytics


i2i(from 2010-08-24)
Total =
Today  =  
Yesterday=
アンチエイジング

Google Analytics
ブックマーク