• ベストアンサー

日本語混じりのファイルをランダムアクセスで読みこむ場合

ファイルを1024バイトずつ読みこみ、その内容をソケットでホストへ送るというアプリがあります。 ファイルを「1024バイト読んで→送信」を繰り返すのですが、ファイルを読みこむところ(Get)で日本語が混じったときにエラーを生じます。 「レコード長が一致しません」というエラーメッセージです。 日本語がはいる桁数だけバイト数は減るためだと思いますが、ランダムアクセスで読みこむと場合の記述の仕方で、何とかならないものかと思案しています。 どなたかご教授ください。よろしくお願いします。 <プログラム記述例>   Dim filenum As Integer   Dim filename As String   Dim buffer As String * 1024   filename = "e:\tmp\file.txt"   filenum = FreeFile   Open filename For Random Access Read As #filenum Len = 1024   Do While Not EOF(filenum)     Get #filenum, , buffer   Loop   Close #filenum

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

  • ベストアンサー
  • TAGOSAKU7
  • ベストアンサー率65% (276/422)
回答No.4

すいません。現在VB環境が無いから・・・ さっきのバグってます・・・ さっきの誤り部分   buffer = Space(lngLen - 1)      'ファイルをバイト単位ではなく、全部取得   Open filename For Random Access Read As #filenum   Get #filenum, , buffer   Close #filenum 本当は・・・   buffer = Space(lngLen)     'ファイルをバイト単位ではなく、全部取得   Open filename For Binary Access Read As #filenum   Get #filenum, , buffer   Close #filenum と置き換えたらできると思うのですが・・・ 環境が無いので未実行です。

参考URL:
http://oshiete1.goo.ne.jp/kotaeru.php3?q=154509
lily02
質問者

お礼

ありがとうございます。 まだソケット通信していませんが、ファイルの読み込みではOKでした。 これから顧客先で試してみます。

その他の回答 (4)

  • imogasi
  • ベストアンサー率27% (4737/17069)
回答No.5

#3の者です。Input$がシーケンシャル用であるのは 知っています。しかしランダムファイルは1連の文字列の ストリームで、レコードごとのデリミタも無く、第nレコードはp=(nー1)*RecLen+1からRecLenバイトの文字列レコードで、RecLenバイトで、全レコードについて意味が完結しているべきものと思います。質問の中から、RecLenバイトで切ると、意味的に、ちょちょ切れているようであるので、このファイルはランダムファイルとして扱うことが破綻していると言う事ではないでしょうか。私は全角シフトイン・アウトの数がレコードごとに変わり意味的長さが変動するケースを経験したような気がするがそんなケースでしょうか(注)RecLenはレコード長を勝手に私が造語。

lily02
質問者

お礼

No1、No4のTAGOSAKU7さんの一括してBinaryで読みこむ方法でうまくいきました。 読みこんでからは、Strconv(buffer,vbFromUnicode)で Unicode からシステムの既定のコード ページに変換して、LenB(buffer)で長さを調べて、送信データはまた Strconv(buffer,vbUnicode)で Unicode に戻すなど、やっかいでしたがなんとか解決しました。どうもありがとうございます。

  • imogasi
  • ベストアンサー率27% (4737/17069)
回答No.3

ダメの様に思いますが、(VBの2,3の本に記載無し) 旧Dos-BasicのステートメントにはInput$があります。Input$ (<ファイルから読みこむ文字のバイト数を指定> <#とファイル番号>) VBでも使えないかチェックしてください。当方データが無くチェックできませんので。

lily02
質問者

お礼

どうもありがとうございます。 Input$関数はシーケンシャルモードとバイナリモード用ですので使えませんでした。ランダムアクセスではGet関数以外にないものでしょうか。

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.2

Binaryモードで開いて、1024バイトづつ読み取るようにすれば。 ランダムアクセスする場合は、seekで移動して。

lily02
質問者

お礼

どうもありがとうございます。 Binaryモードでも試しました。しかし、データ型がStringでないと送信するときにまずいのです。それでBYTE から Stringにうまく変換できなくて(日本語のところ)挫折しました。BYTE(1024)をStringに変換する方法をご存知でしたらお教えください。

  • TAGOSAKU7
  • ベストアンサー率65% (276/422)
回答No.1

バイト数がバラバラなら、ゲットで分割取得の方法は無理ではないかな? いっそのこと、一行単位で読み込むか、全部読み込むかをした方がいいと思います。   Const DEF_SEND_LEN As Long = 1024   Dim filenum   As Integer   Dim filename  As String   Dim buffer   As String   Dim lngLen   As Long   Dim varWk    As Variant   Dim strWk    As String   Dim i      As Long   filename = "e:\tmp\file.txt"   filenum = FreeFile      lngLen = FileLen(filename)   buffer = Space(lngLen - 1)      'ファイルをバイト単位ではなく、全部取得   Open filename For Random Access Read As #filenum   Get #filenum, , buffer   Close #filenum      '配列に分解   'サンプルは改行コードで分解   varWk = Split(buffer, vbCrLf)      '配列ループ   For i = LBound(varWk) To UBound(varWk)     '配列単位で文字列取得     strWk = varWk(i) & Space(DEF_SEND_LEN)     'DEF_SEND_LEN定数バイト数の文字列に変換     strWk = StrConv(LeftB(StrConv(strWk, vbFromUnicode), DEF_SEND_LEN), vbUnicode)          'ここで送信   Next i

lily02
質問者

お礼

TAGOSAKU7さん、お久しぶりです。またいち早く回答をいただき感激です。 早速試してみました。全部読みこむという発想はとても新鮮でした。 しかし、同じエラーでした。ランダムアクセスでは読みこむバイト数をしっかり指定しないとダメなのでしょうか。

関連するQ&A