- ベストアンサー
日本語混じりのファイルをランダムアクセスで読みこむ場合
ファイルを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
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
すいません。現在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 と置き換えたらできると思うのですが・・・ 環境が無いので未実行です。
その他の回答 (4)
- imogasi
- ベストアンサー率27% (4737/17069)
#3の者です。Input$がシーケンシャル用であるのは 知っています。しかしランダムファイルは1連の文字列の ストリームで、レコードごとのデリミタも無く、第nレコードはp=(nー1)*RecLen+1からRecLenバイトの文字列レコードで、RecLenバイトで、全レコードについて意味が完結しているべきものと思います。質問の中から、RecLenバイトで切ると、意味的に、ちょちょ切れているようであるので、このファイルはランダムファイルとして扱うことが破綻していると言う事ではないでしょうか。私は全角シフトイン・アウトの数がレコードごとに変わり意味的長さが変動するケースを経験したような気がするがそんなケースでしょうか(注)RecLenはレコード長を勝手に私が造語。
お礼
No1、No4のTAGOSAKU7さんの一括してBinaryで読みこむ方法でうまくいきました。 読みこんでからは、Strconv(buffer,vbFromUnicode)で Unicode からシステムの既定のコード ページに変換して、LenB(buffer)で長さを調べて、送信データはまた Strconv(buffer,vbUnicode)で Unicode に戻すなど、やっかいでしたがなんとか解決しました。どうもありがとうございます。
- imogasi
- ベストアンサー率27% (4737/17069)
ダメの様に思いますが、(VBの2,3の本に記載無し) 旧Dos-BasicのステートメントにはInput$があります。Input$ (<ファイルから読みこむ文字のバイト数を指定> <#とファイル番号>) VBでも使えないかチェックしてください。当方データが無くチェックできませんので。
お礼
どうもありがとうございます。 Input$関数はシーケンシャルモードとバイナリモード用ですので使えませんでした。ランダムアクセスではGet関数以外にないものでしょうか。
- osamuy
- ベストアンサー率42% (1231/2878)
Binaryモードで開いて、1024バイトづつ読み取るようにすれば。 ランダムアクセスする場合は、seekで移動して。
お礼
どうもありがとうございます。 Binaryモードでも試しました。しかし、データ型がStringでないと送信するときにまずいのです。それでBYTE から Stringにうまく変換できなくて(日本語のところ)挫折しました。BYTE(1024)をStringに変換する方法をご存知でしたらお教えください。
- TAGOSAKU7
- ベストアンサー率65% (276/422)
バイト数がバラバラなら、ゲットで分割取得の方法は無理ではないかな? いっそのこと、一行単位で読み込むか、全部読み込むかをした方がいいと思います。 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
お礼
TAGOSAKU7さん、お久しぶりです。またいち早く回答をいただき感激です。 早速試してみました。全部読みこむという発想はとても新鮮でした。 しかし、同じエラーでした。ランダムアクセスでは読みこむバイト数をしっかり指定しないとダメなのでしょうか。
お礼
ありがとうございます。 まだソケット通信していませんが、ファイルの読み込みではOKでした。 これから顧客先で試してみます。