教えて! goo のコンテンツに対する取り組みについて

VB6ではFileSystemObjectでFileオブジェクトを生成して、
Sizeプロパティからファイルサイズ(バイト)を取得出来ますが、
単純にシーケンシャル入力モードで開いたファイルから、
各行を読み込み、その行の文字列のバイト数を都度加算して行けば
最終的なファイルサイズ(バイト)が取得出来ると考えたのですが、
実際同じ値になりません。

例えば、Sizeプロパティでは、35023バイトのファイルが、
文字列のバイト数を「LenB」で都度加算した場合、
Line Input文で38726バイト、Input文では19363バイトになります。

文字列のバイト数を「Len」で都度加算した場合、
Line Input文で19363バイト、Input文では19361バイトになります。

ファイルは単なるテキストデータです。
なぜ差が出るかの原因を御存知の方教えて頂けませんか?
また同じ値になる方法はあるのでしょうか?
よろしくお願いします。

gooドクター

A 回答 (2件)

そのファイルの中身が漢字混じりのテキストファイルなのではありませんか



VBの内部では漢字など文字列はUnicodeに置き換わります
つまり『abcdef』といった半角英数の文字もUnicodeになります
Shift-JISの場合上記の『abcdef』のLenBは5を返します
Unicodeの場合には10を返します
Shift-JISの場合メモリー上には 41 42 43 44 45 といった並びになります
Unicodeの場合メモリー上には 41 00 42 00 43 00 44 00 45 00 といった並びになります

LenとLenBの違いですが半角英数のみならLenはUnicodeでもShift-JISでも同じ値になります
漢字入ってくるとLenは違う値を返します
Shift-JISの場合『あなたのName』の場合12、Unicodeの場合8になります
つまりUnicodeでのLenは1文字が何個あるかを数えます

おやりになりたいことは
ファイルシステム上のデータの持ち方とVB内部でのデータの持ち方を同一になるようにしてカウントしましょう

Shift-JISのファイルであるなら
dim ss as String
dim buf() as Byte
dim nLen as Long
Open "ファイル名" for Input as #1
do until eof
  ' Line Input でつぶされた CRLF分を+2
  if nLen > 0 then nLen = nLen + 2
  Line Input #1, ss
  buf = strconv( ss, vbFromUnicode )
  ' Byte配列は0ベースなので + 1する
  nLen = nLen + Ubound(buf) + 1
loop
close
といった具合でやってみましょう
    • good
    • 0

LenBは半角なら1、全角なら2が返ると思っているのでは?


LenBは内部形式、即ち、UniCodeのバイト数が返ります。つまり、
いずれも2が返ります。Lenは文字数が返りますので、いずれの
関数の戻り値を累積してもファイルのバイト数にはなりません。
但し、ファイルがUniCodeテキストで、改行が無い時は別です。
次に、Line Input文では復帰+改行が入ってきませんので、
1行毎に2バイトのズレが生じます。Input文では区切り文字や
引用符もとれてしまうので、更に乖離が大きくなります。
ファイルサイズを得るにはFileLen関数、またはLOF関数を使います。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

gooドクター

人気Q&Aランキング