Input 命令語では一行目しか取得できないのですが

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
NON

Input 命令語では一行目しか取得できないのですが

#1 投稿記事 by NON »

ActiveBasic を使わせてもらっています。
ファイルを読み込もうとしているのですが、タイトルのとおり、
Input 命令語では頭の1行だけしか取得できません。
全部読み込むにはどうすればいいのでしょうか?
BingoMan
記事: 36
登録日時: 2005年7月17日(日) 09:36
お住まい: 千葉県松戸市

#2 投稿記事 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
イグトランス
記事: 899
登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:

#3 投稿記事 by イグトランス »

大筋はそれで問題ないですが、どうしても気になることがあるもんで。

> buffer=String$(dwFileSize,Chr$(0))
これはbuffer = ZeroString(dwFileSize)の方が良いです。
なぜかというとString$はまずZeroStringで文字列を確保して、そこへ2番目の引数の文字列を並べるということをしています。
Chr$(0)なら後半の作業をやる必要がないのでその分時間のロスです。

> File_Open=String$(dwFileSize,Chr$(0))
これも直後で代入するときに改めて文字列の領域が確保されなおされるでしょうからたぶん無駄足です。
> File_Open=buffer
BingoMan
記事: 36
登録日時: 2005年7月17日(日) 09:36
お住まい: 千葉県松戸市

#4 投稿記事 by BingoMan »

イグトランス様、ご指摘ありがとうございます。
自分のライブラリもSrting$関数からZeroString関数に変えさせていただきました。
NON

ありがとうございます

#5 投稿記事 by NON »

ありがとうございます。おかげで出来ました。
NON

バイナリデータが・・・

#6 投稿記事 by NON »

バイナリデータがうまく読み込めません。
読み込めるのはテキストデータだけでしょうか?
まけイヌ
記事: 27
登録日時: 2005年7月03日(日) 10:37
お住まい: 愛知県岡崎市
連絡する:

Re: バイナリデータが・・・

#7 投稿記事 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までは正常動作します
# まけイヌ (losedog2)
# Home : http://www50.tok2.com/home/losedog2/
# Mail : losedog2@yahoo.co.jp
NON

やはりバイナリデータは読み込めない

#8 投稿記事 by NON »

作成していただいたコードでもバイナリデータは取得できませんでした。
皆さんの迷惑になりそうなのでここで一応止めますが、
どなたか読み込む方法ご存知の方いましたらご教授ください。
まけイヌ
記事: 27
登録日時: 2005年7月03日(日) 10:37
お住まい: 愛知県岡崎市
連絡する:

Re: やはりバイナリデータは読み込めない

#9 投稿記事 by まけイヌ »

> 作成していただいたコードでもバイナリデータは取得できませんでした。
??
このコード、私自身がビットマップ全体をロードしたり、
ショートカットやJpegフォーマットの解析をしたり、
はたまたバイナリエディタを作ったりと
使いまわしているコードなんですが..

ちなみに「読めない」とおっしゃるバイナリデータとやらの
サイズはどのくらいでしょうか?
# まけイヌ (losedog2)
# Home : http://www50.tok2.com/home/losedog2/
# Mail : losedog2@yahoo.co.jp
NON

#10 投稿記事 by NON »

1Mバイト以下です。おそらくプログラムのほうが変なのだとおもいます。
「Asc」などををする関係で、BytePtr 型として取得したデータを
「MakeStr」で String 型に変換して使っています。
MIDIデータで実験しているのですが、頭の「MThd」しか
読み込めていないようです。
hira
記事: 203
登録日時: 2005年5月31日(火) 20:14
お住まい: 兵庫県
連絡する:

Re: やはりバイナリデータは読み込めない

#11 投稿記事 by hira »

MakeStr関数は、NULL文字(0x00)までで文字列を切ってしまいます(もともと、BytePtr型で表された文字列をString型で表すためのもので、バイナリデータに使うものではありません)。
MIDIのヘッダの場合、MThd の次には0x00が来ます。そのため、そこまでで切られてしまって MThd しかなくなってしまったと思われます。
そのため、可能ならばBytePtr型のまま処理してください。
なお、通常 Asc(Mid$(String,n,1)) = String[n-1] です。つまり、Asc関数を使わなくても、添え字を指定することで同じことができます。
NON

#12 投稿記事 by NON »

コード: 全て選択

databuf= fload(buf)
fb=lstrlen(databuf)
msgbox 0,Str$(fb)
buf ファイルのアドレス
fb ファイルサイズ格納用
databuf BytePtr 型のデータ格納用

このプログラムで、実行ファイルを読むと、「3」と言われます。
こちらの環境の問題でしょうか?
Sinryow
記事: 141
登録日時: 2005年5月31日(火) 09:34
お住まい: 北海道
連絡する:

#13 投稿記事 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)

※実験していないのでうまくいかなかったらすみません
' ============================================================
' Sinryow Game Home Page - http://www.sinryow.net/
' Sinryow ActiveBasic Center - http://ab.sinryow.net/
' ============================================================
NON

読み込めました

#14 投稿記事 by NON »

ありがとうございます。読み込めるようになりました。
返信する