バイナリデータから指定範囲を取得する方法

このQ&Aのポイント
  • VB6でテキストファイルをバイナリモードで開き、特定の位置から必要な分を取得し、ファイルを分割させる方法について教えてください。
  • コード内にはOpen、ReDim、Get、Put、Closeなどの関数が使用されていますが、指定されたバイト数目から指定されたバイト数までのデータを取得する方法がうまくできていないようです。
  • 望む結果を得るためにはどのような修正が必要でしょうか。お助けください。
回答を見る
  • ベストアンサー

バイナリデータの中からMidのように指定範囲を取得したい

教えて下さい。 VB6です。 テキストファイルをバイナリモードで開き、Midのように特定の位置から、 必要な分を取得し、ファイルを分割させたいです。 調べてたら、 Open 読込ファイル For Binary As #1 Open 書込ファイル For Binary As #2 ReDim bytData(1 To LOF(1)) Get #1, , bytData() Put #2, , bytData() close #1 close #2 というのを見つけました。これだとそのままコピーします。 ここから、指定された、バイト数目から指定されたバイト数までの データを取得し別のファイルを作りたいのですが、 うまくできません。どうしたら、望むことができるでしょうか? お助け下さい。

質問者が選んだベストアンサー

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

文字化けするとのことですが そのファイルはUnicodeテキストファイルでしょうか? Unicodeですと ファイルの先頭に &HFF &HFEという2バイトのサインが必要です また 全てが2バイトで表現されていますので切り出す位置が偶数バイト目になるようにしないといけないかと思います ReDim byData( LOF(1) )といった具合にして 0ベースにしたほうが計算が楽ですよ 1 to にすると最後の1バイトは読み込みませんよ ユニコードなら for文を ReDim ar( バイト数 + 2 ) ar(0) = 255 ar(1) = 254 for n=2 to バイト数   ar(n) = byData( ( n - 2 ) + オフセット ) next といった具合にして見ましょう

その他の回答 (1)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

普通に考えれば ベタにfor文でループしてコピーでしょう dim n as integer, ar() as byte ReDim ar(必要な要素数) Open 読込ファイル For Binary As #1 ReDim bytData(1 To LOF(1)) Get #1, , bytData() Close #1 for n=0 to 必要な要素数 ar(n) = byData(n + 必要な要素へのオフセット) next Open 書込ファイル For Binary As #2 Put #2,,ar() Close #2 といった具合です

satoshi777
質問者

補足

redfox63さん、いつもありがとうございます。 早速やってみましたが、必要箇所だけでなく、やはり全てを取得してしまいます。おまけにノートパッドで開くと化けています。元データは、 ぱっと見、普通のテキストデータです。 Dim 開始位置 as long Dim 終了位置 as long Dim 文字数 as long 文字数 = 終了位置 - 開始位置 Dim n As Integer, ar() As Byte Dim bytData() As Byte ReDim ar(Val(文字数)) Open 読込ファイル For Binary As #1 ReDim bytData(1 To LOF(1)) Get #1, , bytData() Close #1 For n = 0 To 文字数 ar(n) = bytData(n + 開始位置) Next Open 書込ファイル For Binary As #2 Put #2, , ar() Close #2 という風にお手本をいじったのですが、間違いがあるでしょうか? 何度もすいません。

関連するQ&A

  • InetコントロールHTTPでバイナリファイルをサーバにPUTする。

    Inetコントロールを使用してHTTPでサーバ上にバイナリファイルを送信使用としています。 ExecuteメソッドのPUTを使用してみましたが、サーバ上のファイルサイズが0KBになってしまい、正常に送信されていません。 Dim bData() As Byte Dim intFile As Integer intFile = FreeFile() Open "D:\Temp\aaa.mdb" For Binary Access Read As #intFile ReDim bData(0 To LOF(intFile) - 1) 'ここでは、bDataに読み込めている。 Get #intFile, , bData Close #intFile Inet1.Execute "http://aaserver/files/aaa.mdb", "PUT", bData よろしくお願いします。

  • VB(VBA)で、バイナリデータを使ってテキストファイルを作成したいの

    VB(VBA)で、バイナリデータを使ってテキストファイルを作成したいのですが、 例えば、"A"が一文字のみのShift-JIS もしくはunicodeのテキストファイルを作るため、 (下記の確認はShift-jis で行っています。) Dim ByteData As Byte ByteData = AscW("A") Open "C:\A.txt" For Binary Access Write As #1 Put #1, 1, ByteData Close #1 としました。 できあがったファイルをバイナリエディタで確認すると、  41 となっています。 (Unicode は 41 00 2バイト文字でリトルエンディアンのため) この41は、"A" の文字コード(Shift-JIS)「65」の16進表記です。 この「41」という値を使ってバイナリモードでテキストファイルを作成したいのですが、 どのようにすればよいでしょうか? 上記 Put #1, 1, ByteData の部分を、 1.Put #1, 1, 41 としたところ、通常表示はできないファイルができあがったみたいです。 バイナリモードで 「29 00 20 20」でした。 文字コード00 に該当する文字がないためだと思います。 2.Put #1, 1, "41" としたところ、「41 」(バイナリモードで 「34 31 20 20」) (41の後ろは半角空白) で×でした。 3.Put #1, 1, CLng("&H" & 41) としたところ、通常表示はできないファイルができあがったみたいです。 バイナリモードで 「41 00 00 00」でした。 4.ByteData = CLng("&H" & 41) Put #1, 1, ByteData これでやっとできました。 この他にも方法があるのか?と思い、質問させていただきました。 ご指導よろしくお願いいたします。

  • VBAでバイナリデータが上手く読めない。

    VBAでバイナリデータが上手く読めない。 もともとC言語でバイナリデータを加工していた事をVBAでやる事になったのですが、上手く読めない。 <VBA> Open inputFileName For Binary As #mFileNo のようにオープンして、 <VBA> Dim a(800) As Byte Get #1, , a のように記述すればC言語のように取得出来ると思ったのですが、上手く取得出来ません。 なんとなく分かった事ですが、800バイトの中に改行文字があった場合、そこまでを変数aに入れるようにすると出来そうなので、Getで改行コードがあった場合はそこまでを読み込むみたいな手段はありますでしょうか。inputだとデータがまったく見れませんでしたのでGetにて対応したいと思っています。 宜しくお願い致します。

  • バイナリデータのファイル入出力について

    ○No.1 Open filename For Binary Access Read As #1 Get #1, , 変数 Close #1 ○No.2 Open filename For Input As #1 Line Input #1, 変数 Close #1 No.1とNo.2のプログラムでは読み込み方にどのような違いがあるのでしょうか?たとえば、No.2のLine Inputでは改行文字は読み飛ばされますが、No.1は改行文字も読み込みますよね。また、No.1ではDim 変数 As String * 1と最後の* 1など文字の読み込み数を定義しておく必要がありますが、Line Inputに対応するものがないからでしょうか? また、バイナリデータを読み書きするときに他に良いコードというかこうするのが定石みたいなのがあったら教えてください。

  • バイナリデーター内の文字を検索

    現在、以下のようなプログラムでバイナリファイルを読込んでいるのですが、そのデーターの中にある文字列の位置を検索したいのですが何かよい方法は無いでしょうか、for ~ next で廻すと一応はできますが、もう少し簡単な方法を探しています。 -------- Dim xBIN() As Byte Dim lngFileLenB As Long lngFileLenB = FileLen("バイナリ.BIN") Open "バイナリ.BIN" For Binary As #1 Get #1, , xBIN ' For i = 0 To lngFileLenB If IJP_DAT1(i) = CLng("&H" & "20") Then stop end if next i ---------- よろしくお願いします。

  • 【VB6.0】ファイルからサイズの大きいバイナリデータを読み込む際にエラー

    はじめまして。 初投稿の新米プログラマです。 VB6.0で多種類のファイルをバイナリデータとして読み込んで 返却する関数を作成しています。 '------------------------------------- ' ファイルからバイナリデータを読み込む '------------------------------------- private Function GetBinaryData(ByVal strFileName As String) As Byte() On Error GoTo Exception Dim fileNo As Integer Dim fileSize As Long Dim bytData() As Byte 'ファイルのサイズを取得する fileSize = FileLen(strFileName) ReDim bytData(fileSize - 1) 'バイナリデータ読み込み fileNo = FreeFile Open strFileName For Binary Access Read As fileNo Get #fileNo, , bytData Close #fileNo '戻り値の設定 GetBinaryData = bytData Exit Function 'エラー処理 Exception: MsgBox (CStr(Err.Number) & " " & Err.Description) End Function ですが、↑の関数にサイズの大きなファイル(100M程度)を指定したとき  ReDim bytData(fileSize) で、「メモリが不足しています」というエラーが発生してしまいます。 発生の仕方としては、'エラー処理のMsgBoxで表示されることも ありますし、プログラムが停止することもありますし、 On Error GoToを記述しているのにも関わらず VBのメッセージボックスが表示されることもあります。  #[継続][終了][デバッグ][ヘルプ]のボタンが出ているやつです。 ちなみに、50M程度のファイルであれば読み込めています。 このエラーが発生する原因は何なのでしょうか? また、解決方法(サイズの大きなファイルを確実に読み込む方法)は あるのでしょうか? 解決方法がないのであれば、「○M以上のファイルはエラー」という 仕様にしようと思うのですが、 何Mまでなら確実に読み込むことが出来るのでしょうか? …もしくは上のコーディング自体、検討違いでしょうか^^;  #バイト配列の要素数に上限があるとか…? とても困っています… どうかよろしくお願い致します。

  • バイナリデータの取り方

    VB6を使用して、バイナリファイルをバイナリデータとして文字列にとりたいのですが、全角文字が絡んだ時の処理がうまくいきません。 バイナリファイルをString型の変数に丸ごと読み込んで、後は何バイトから何バイト目を抜き取り数値に変換…という処理をしようとしています。 本来は、バイナリでファイルをオープンして、Getコマンドで取得するのが手っ取り早いのですが、ファイルアクセス回数を減らすため、このような面倒な方法をとっております。 そこで仮に、 dim test as string dim i as integer test = "aあ" & chr(1) & "0 " For i = 1 to 6 Debug.Print Asc(Strconv( _ MidB(Strconv(test,vbFromUnicode),i,1), _ vbUnicode)) Next のようなソースを作ってみました。(本来は文字列は数100KByte…) しかしながら、この方法ですと上の例では2Byte目、つまり「あ」の文字の1Byte目が「&H00」になってしまいます。その次は「&HA0」、他の箇所も問題ないのですが… おそらくは根本的に違う方法で解決すべきではないかと思うのですがその方法がわかりません。 なお、この格納データはバイナリデータなので、意図的に全角文字にしていくてもその値によって(偶然)全角文字になったり制御文字になったりしますので前もって全角文字に対する処理は難しいと考えてます。 質問の仕方が良くなく、質問の内容がなかなかご理解いただけないとは思いますが、ご存知の方、ご経験者の方、ご教授お願いいたします。

  • VBA(Access)でバイナリデータから日付を取得したい。日付は生年

    VBA(Access)でバイナリデータから日付を取得したい。日付は生年月日なのですが、VC++で行っていた作業を今度はVBA(Access)でやる事になり困っています。 <C++> int n,fd; char str[805],birthday[20],*p; fd = open(path, O_RDONLY); n = read(fd, str, 0x800); p=&buf[5*16+5+(16*21+6)]; sprintf(birth,"%08d",*((unsigned int*)(p-4))); 上記だと西暦がちゃんと取れます。 例>1990年4月5日だと⇒19900405のように取れます。 <VBA> VBA(Access)の場合どのように作成すれば良いでしょうか。 Dim b As String * 800 Dim str As String * 20 Open "Path.dat" For Binary As FreeFile Get # FreeFile, , b *適当に書いてしまいました。 str = mid$(b,55,8)   '←分からない部分 C++だと分かるのですが、VBAではどのように記述するのでしょうか。 とても雑で見にくいプログラムになっていますが、ご了承ください。 どのようにデータを取得しても化け文字で表示されてしまいます。 宜しくお願いします。

  • バイナリ形式でデータの入出力をしたい

    STLやstringが規格化されていない時代の古いC++の本しか持っていない私の唯一の教科書はマイクロソフトのライブラリだけなのですが時々どこに必要な事項が載っているか探しきれないことがあります その1つとして バイナリデータを読み出したり書きこんだりするにはどうするかということです バイナリファイルinfile.exeの読み出のためのファイルとの接続として ifstream ifs; ifs.open("infile.exe",ios::in|ios::binary); としバイナリファイルoutfile.exeの読み出しのためのファイルとの接続として ofstream ofs; ofs.open("outfile.exe",ios::out|ios::binary|ios::trunc); としましたがこれは正しいやり方なのでしょうか? もし不備があれば指摘してください とくにファイル名の次のモードについて指摘していただければ幸いです (なかでもios::truncが心配)

  • バイナリーファイルの追記

    VB初心者です。 3レコードからなる90バイトのバイナリーファイルの 最後のレコードだけを上書きしたいのですが、うまく いきません。どう書けば良いのでしょうか? 宜しくお願い致します。 '------------------------------------------------ Public Type REC_INFORMATION AA As Long BB As Single CC As Single DD As Single EE As Single FF As Single GG As Single HH As Integer End Type Public RecInfo As REC_INFORMATION '------------------------------------------------------------- Dim ByteCNT as Long RecInfo.AA = CLng("123") RecInfo.BB = CSng("123") RecInfo.CC = CSng("123") RecInfo.DD = CSng("123") RecInfo.EE = CSng("123") RecInfo.FF = CSng("123") RecInfo.GG = CSng("1") RecInfo.HH = CInt("1") Open "c:\TEST.bin" For Binary As #1 ByteCNT = LOF(1) Seek #1, (ByteCNT - 29) Put #1, , RecInfo Close #1

専門家に質問してみよう