QA@IT
この質問・回答は、@ITの旧掲示板からインポートされたものです。

固定長テキストの読み込み(VB.NET)

いつもお世話になっております。
固定長テキストファイルから、指定したバイト数の文字列を取得しようとしております。
テキストに日本語(2Byte文字)が含まれていた場合に、正常に読み込むことができません。

【開発環境:】-----------
VisualStdio2005(VB.NET)
SQLServer2005

【ソース】-----------
Dim Reader As IO.StreamReader
Dim GetStr As String
Dim UpdateData(5) As Char
dim a as string
dim b as string
Reader = New IO.StreamReader("D:\test.text")

try
do while reader.peek() > -1

        Convert.ToString(Reader.Read(UpdateData, 0, 5))
    GetStr = Convert.ToString(UpdateData)

    a = mid(getstr,0,2)
    b = mid(getstr,2,4)

〜(省略)〜
loop
〜(省略)〜
end try

【結果】-----------
test.textの内容が
112233445566778899.....
の場合は
a = 11
b = 2233
(以降続けて、a = 44,b=5566)
と正常に読み込むことができました。

しかしtest.textの内容が
11ああ33いい55うう
などと日本語を入力した場合に
a = 11
b = 3355
とbが正常に取得できておりません。

GetStrに格納する時点で、日本語が取得できていない模様です。

【取得したい内容】-----------
a = 11
b = ああ
(以降続けて、a = 33,b=いい)
と日本語についても変数に格納したいと思います。

Dim UpdateData(5) As Char
とchar型での宣言をしているため、Reader.Readで格納した際に切り取られてしまったものと思われるのですが・・・

日本語についても取得できるようにするためには、どのようにいたせばよろしいでしょうか?
(こういった固定長のテキストファイルを読み込む際に、StreamReaderなどの使用でよろしいのでしょうか?)

質問者:NGO

回答

System.IO 名前空間の Stream クラス(対象がローカルのファイルなら、Stream の派生クラスである FileStream クラス)を使って Byte 配列に読み出すべきですね。
その後、System.Text 名前空間の Encoding クラスの各種派生クラスを使って文字列に変換します。Shift_JIS は、日本語版の OS 上では Encoding.Default を使用できますが、それ以外のことも考えれば Encoding.GetEncoding メソッドを使った方が安全でしょう。

ちなみに、StreamReader は既定では UTF-8 として解釈します。
そもそも StreamReader(TextReader)は文字列としてストリームを解釈するためのクラスであり、処理はバイト単位ではなく文字単位です。
それから、


Convert.ToString(Reader.Read(UpdateData, 0, 5))

これの意味を理解していますか?

投稿者:Hongliang

編集 履歴 (0)

Hongliang様、ご返信ありがとうございます。

対象はローカルファイルです。
「Byte配列に」
ということでしたので

Dim test As New FileStream("D:\test.text", FileMode.Open, FileAccess.Read, FileShare.None)

と宣言し、

Dim r As New BinaryReader(test)

とした上で、デバッガ上で
r.ReadString
をチェックしてみたところ

1回目のr.readstring :11
2回目のr.readstring :33
と日本語部分が表記されませんでした。
readstring というのが、根本的に間違っているのでしょうか?

>Convert.ToString(Reader.Read(UpdateData, 0, 5))
UpdateDataをデバッグ上でみてみると
[1]1
[2]1
[3]3
[4]3
などと一文字ずつのCharのデータが格納されておりました。
「Reader.readで取得したデータを位置0から5文字取得して、string型へコンバートしろ」
という意味だと解釈しておりました。
そのため、
1133....
となったと思っております。

Dim UpdateData(5) As Char
とcharで宣言している状態だったため、2byteの文字が切られたものかと・・・。

投稿者:NGO

編集 履歴 (0)

http://dobon.net/vb/dotnet/file/filestream.html
を参考に、BinaryStreamの箇所を下記のように変更いたしました。
(バイト型配列に格納後にencodingでUTF8に変換)
Dim bs(5) As Byte
test.Read(bs, 0, bs.Length)
GetStr = System.Text.Encoding.UTF8.GetString(bs)

getstr.tostring

で値をチェックしてみたのですが、同じく日本語の部分が飛ばされておりました。
1133

引き続き、いただいたアドバイスを元に調べてみます。

投稿者:NGO

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。