ページ 1 / 1
Input 命令語では一行目しか取得できないのですが
Posted: 2005年7月17日(日) 19:02
by NON
ActiveBasic を使わせてもらっています。
ファイルを読み込もうとしているのですが、タイトルのとおり、
Input 命令語では頭の1行だけしか取得できません。
全部読み込むにはどうすればいいのでしょうか?
Posted: 2005年7月17日(日) 20:26
by BingoMan
おそらく次のような関数で全部読み込めると思います。
コード: 全て選択
Function File_Open(Path As String)As String
Dim File As DWord
Dim dwFileSize As DWord
Dim dum As Long
Dim buffer As String
File=CreateFile(Path,GENERIC_READ,FILE_SHARE_READ,_
ByVal NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,0)
If File=INVALID_HANDLE_VALUE Then File_Open="":ExitFunction
dwFileSize=GetFileSize(File,0)
buffer=String$(dwFileSize,Chr$(0))
ReadFile(File,buffer,dwFileSize,VarPtr(dum),ByVal NULL)
CloseHandle(File)
File_Open=String$(dwFileSize,Chr$(0))
File_Open=buffer
EndFunction
Posted: 2005年7月17日(日) 21:36
by イグトランス
大筋はそれで問題ないですが、どうしても気になることがあるもんで。
> buffer=String$(dwFileSize,Chr$(0))
これはbuffer = ZeroString(dwFileSize)の方が良いです。
なぜかというとString$はまずZeroStringで文字列を確保して、そこへ2番目の引数の文字列を並べるということをしています。
Chr$(0)なら後半の作業をやる必要がないのでその分時間のロスです。
> File_Open=String$(dwFileSize,Chr$(0))
これも直後で代入するときに改めて文字列の領域が確保されなおされるでしょうからたぶん無駄足です。
> File_Open=buffer
Posted: 2005年7月17日(日) 23:53
by BingoMan
イグトランス様、ご指摘ありがとうございます。
自分のライブラリもSrting$関数からZeroString関数に変えさせていただきました。
ありがとうございます
Posted: 2005年7月18日(月) 07:44
by NON
ありがとうございます。おかげで出来ました。
バイナリデータが・・・
Posted: 2005年7月19日(火) 19:58
by NON
バイナリデータがうまく読み込めません。
読み込めるのはテキストデータだけでしょうか?
Re: バイナリデータが・・・
Posted: 2005年7月19日(火) 21:37
by まけイヌ
> バイナリデータがうまく読み込めません。
> 読み込めるのはテキストデータだけでしょうか?
Inputの仕様は連続するNULLターミネートされた文字列も条件です。
つまり、
・カンマ
・改行
・NULL
のいずれかにヒットすると読み込みをやめてしまいます。
恐らくBingoMan様のソースにイグトランス様の改良を加えたバージョンが
一番正確にバイナリデータの確保を行えると思います。
<<蛇足>>
このソースでも4GB以上のファイルは正常に読み込めません。
符号無し型のDWord型を使うので4GB = 0Byteとなってしまいます。
これを有効にするには、GetFileSize関数(API)の第2引数の0に
きちんと0で初期化されたDWord型変数を与えてやり、
関数実行後にこの変数を評価する必要があります。
コードにするとこんな感じです。
コード: 全て選択
'■ファイル内バッファを取り込む
Function fload ( ByVal lpstrFileName As BytePtr) As BytePtr
Dim hFile As HFILE
Dim dwSizeOver As DWord
Dim dwSizeLower As DWord
Dim qwSize As QWord
fload = NULL
hFile = CreateFile( lpstrFileName, GENERIC_READ, 0,ByVal 0,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0)
If hFile = INVALID_HANDLE_VALUE Then Exit Function
dwSizeOver = 0
dwSizeLower = GetFileSize( hFile, VarPtr(dwSizeOver))
If dwSizeOver = 0 Then
qwSize = dwSizeLower
Else
qwSize = (dwSizeOver * &h100000000) + dwSizeLower
End If
fload = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, qwSize)
ReadFile( hFile, fload, qwSize, VarPtr(dwSizeOver), ByVal 0)
CloseHandle (hFile)
End Function
'■バッファを開放する
Function fclose ( ByVal lpstrBuffer As BytePtr) As Long
fclose = HeapFree( GetProcessHeap(), 0, lpstrBuffer)
End Function
'■--- ここからが実装部 ---
Dim buf As BytePtr
'■バッファ取り込み
buf = fload("sample.txt")
'--- ここでファイル内バッファに対する処理を書きます ---
'■取り込んだバッファの開放
fclose (buf)
'■終了
End
ただし、HeapAlloc関数(API)やReadFile関数(API)のところでDWord型になっているので、正しくロードできるかどうかは疑問ですが..
※つか、たぶんできません(^^;;;
※このコード自体は4GBまでは正常動作します
やはりバイナリデータは読み込めない
Posted: 2005年7月21日(木) 19:37
by NON
作成していただいたコードでもバイナリデータは取得できませんでした。
皆さんの迷惑になりそうなのでここで一応止めますが、
どなたか読み込む方法ご存知の方いましたらご教授ください。
Re: やはりバイナリデータは読み込めない
Posted: 2005年7月21日(木) 21:21
by まけイヌ
> 作成していただいたコードでもバイナリデータは取得できませんでした。
??
このコード、私自身がビットマップ全体をロードしたり、
ショートカットやJpegフォーマットの解析をしたり、
はたまたバイナリエディタを作ったりと
使いまわしているコードなんですが..
ちなみに「読めない」とおっしゃるバイナリデータとやらの
サイズはどのくらいでしょうか?
Posted: 2005年7月22日(金) 12:48
by NON
1Mバイト以下です。おそらくプログラムのほうが変なのだとおもいます。
「Asc」などををする関係で、BytePtr 型として取得したデータを
「MakeStr」で String 型に変換して使っています。
MIDIデータで実験しているのですが、頭の「MThd」しか
読み込めていないようです。
Re: やはりバイナリデータは読み込めない
Posted: 2005年7月22日(金) 13:38
by hira
MakeStr関数は、NULL文字(0x00)までで文字列を切ってしまいます(もともと、BytePtr型で表された文字列をString型で表すためのもので、バイナリデータに使うものではありません)。
MIDIのヘッダの場合、MThd の次には0x00が来ます。そのため、そこまでで切られてしまって MThd しかなくなってしまったと思われます。
そのため、可能ならばBytePtr型のまま処理してください。
なお、通常 Asc(Mid$(String,n,1)) = String[n-1] です。つまり、Asc関数を使わなくても、添え字を指定することで同じことができます。
Posted: 2005年7月25日(月) 11:56
by NON
コード: 全て選択
databuf= fload(buf)
fb=lstrlen(databuf)
msgbox 0,Str$(fb)
buf ファイルのアドレス
fb ファイルサイズ格納用
databuf BytePtr 型のデータ格納用
このプログラムで、実行ファイルを読むと、「3」と言われます。
こちらの環境の問題でしょうか?
Posted: 2005年7月25日(月) 17:34
by Sinryow
lstrlenも,MakeStr同様'\0'の部分で長さを切ってしまいますのでそうなってしまうのです。
「バッファの長さ=実際に読み込んだ長さ」なのですから,それを利用すればよいだけです。例えば
コード: 全て選択
' ファイルの内容を16進数で表示
' ※エラー処理等はすべて省略
hFile=CreateFile(...)
dwSize=GetFileSize(hFile, NULL)
Dim databuf As BytePtr
databuf=malloc(dwSize)
ReadFile(hFile, databuf, dwSize, VarPtr(dwRead), ByVal NULL)
CloseHandle(hFile)
For i=0 To dwRead-1
Print "["+Hex$(databuf)+"]";
Next
free(databuf)
※実験していないのでうまくいかなかったらすみません
読み込めました
Posted: 2005年7月25日(月) 19:34
by NON
ありがとうございます。読み込めるようになりました。