Input 命令語では一行目しか取得できないのですが
Input 命令語では一行目しか取得できないのですが
ActiveBasic を使わせてもらっています。
ファイルを読み込もうとしているのですが、タイトルのとおり、
Input 命令語では頭の1行だけしか取得できません。
全部読み込むにはどうすればいいのでしょうか?
ファイルを読み込もうとしているのですが、タイトルのとおり、
Input 命令語では頭の1行だけしか取得できません。
全部読み込むにはどうすればいいのでしょうか?
おそらく次のような関数で全部読み込めると思います。
コード: 全て選択
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
大筋はそれで問題ないですが、どうしても気になることがあるもんで。
> buffer=String$(dwFileSize,Chr$(0))
これはbuffer = ZeroString(dwFileSize)の方が良いです。
なぜかというとString$はまずZeroStringで文字列を確保して、そこへ2番目の引数の文字列を並べるということをしています。
Chr$(0)なら後半の作業をやる必要がないのでその分時間のロスです。
> File_Open=String$(dwFileSize,Chr$(0))
これも直後で代入するときに改めて文字列の領域が確保されなおされるでしょうからたぶん無駄足です。
> File_Open=buffer
> buffer=String$(dwFileSize,Chr$(0))
これはbuffer = ZeroString(dwFileSize)の方が良いです。
なぜかというとString$はまずZeroStringで文字列を確保して、そこへ2番目の引数の文字列を並べるということをしています。
Chr$(0)なら後半の作業をやる必要がないのでその分時間のロスです。
> File_Open=String$(dwFileSize,Chr$(0))
これも直後で代入するときに改めて文字列の領域が確保されなおされるでしょうからたぶん無駄足です。
> File_Open=buffer
Re: バイナリデータが・・・
> バイナリデータがうまく読み込めません。
> 読み込めるのはテキストデータだけでしょうか?
Inputの仕様は連続するNULLターミネートされた文字列も条件です。
つまり、
・カンマ
・改行
・NULL
のいずれかにヒットすると読み込みをやめてしまいます。
恐らくBingoMan様のソースにイグトランス様の改良を加えたバージョンが
一番正確にバイナリデータの確保を行えると思います。
<<蛇足>>
このソースでも4GB以上のファイルは正常に読み込めません。
符号無し型のDWord型を使うので4GB = 0Byteとなってしまいます。
これを有効にするには、GetFileSize関数(API)の第2引数の0に
きちんと0で初期化されたDWord型変数を与えてやり、
関数実行後にこの変数を評価する必要があります。
コードにするとこんな感じです。
ただし、HeapAlloc関数(API)やReadFile関数(API)のところでDWord型になっているので、正しくロードできるかどうかは疑問ですが..
※つか、たぶんできません(^^;;;
※このコード自体は4GBまでは正常動作します
> 読み込めるのはテキストデータだけでしょうか?
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
※つか、たぶんできません(^^;;;
※このコード自体は4GBまでは正常動作します
やはりバイナリデータは読み込めない
作成していただいたコードでもバイナリデータは取得できませんでした。
皆さんの迷惑になりそうなのでここで一応止めますが、
どなたか読み込む方法ご存知の方いましたらご教授ください。
皆さんの迷惑になりそうなのでここで一応止めますが、
どなたか読み込む方法ご存知の方いましたらご教授ください。
Re: やはりバイナリデータは読み込めない
> 作成していただいたコードでもバイナリデータは取得できませんでした。
??
このコード、私自身がビットマップ全体をロードしたり、
ショートカットやJpegフォーマットの解析をしたり、
はたまたバイナリエディタを作ったりと
使いまわしているコードなんですが..
ちなみに「読めない」とおっしゃるバイナリデータとやらの
サイズはどのくらいでしょうか?
??
このコード、私自身がビットマップ全体をロードしたり、
ショートカットやJpegフォーマットの解析をしたり、
はたまたバイナリエディタを作ったりと
使いまわしているコードなんですが..
ちなみに「読めない」とおっしゃるバイナリデータとやらの
サイズはどのくらいでしょうか?
Re: やはりバイナリデータは読み込めない
MakeStr関数は、NULL文字(0x00)までで文字列を切ってしまいます(もともと、BytePtr型で表された文字列をString型で表すためのもので、バイナリデータに使うものではありません)。
MIDIのヘッダの場合、MThd の次には0x00が来ます。そのため、そこまでで切られてしまって MThd しかなくなってしまったと思われます。
そのため、可能ならばBytePtr型のまま処理してください。
なお、通常 Asc(Mid$(String,n,1)) = String[n-1] です。つまり、Asc関数を使わなくても、添え字を指定することで同じことができます。
MIDIのヘッダの場合、MThd の次には0x00が来ます。そのため、そこまでで切られてしまって MThd しかなくなってしまったと思われます。
そのため、可能ならばBytePtr型のまま処理してください。
なお、通常 Asc(Mid$(String,n,1)) = String[n-1] です。つまり、Asc関数を使わなくても、添え字を指定することで同じことができます。
[hira]
http://hira.hopto.org/
http://hira.hopto.org/
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/
' ============================================================
' Sinryow Game Home Page - http://www.sinryow.net/
' Sinryow ActiveBasic Center - http://ab.sinryow.net/
' ============================================================