PART5: ファイルの入出力 その2
(2001年9月17日)
前回からかなり間が開いてしまいましたが、前回に引き続きファイルの入出力について書いていきたいと思います。
前回はVB6のファイル入出力プロジェクトからアップグレードウィザードでVB.NETのコードに変換し、そのコードをほんの少しだけ見てみました。
ちなみに前回は
1
2
3
... と入力されたデータを使用し Format関数で成型したデータを表示しましたが、
今回は
01行目
02行目
03行目
... といった具合に日本語を混在させたデータをそのまま表示させてみたいと思います。
以下がアップグレードウィザード後のファイル読み込み部分のコードです。
Dim intFNo As Integer
Dim strBuf As String
intFNo = FreeFile()
FileOpen(intFNo, "D:\TEST.TXT", VB6.OpenMode.Input)
Do While Not EOF(intFNo)
strBuf = LineInput(intFNo)
Text1.Text = Text1.Text & strBuf & ControlChars.CrLf
Loop
VB6.Close(intFNo)
|
ファイルの入出力に関しては、このFileSystemクラスのメソッドを使う方法の他に、もうひとつ方法があります。
ここで話はVB6に戻りますが、VB6でも標準のファイルI/Oステートメントの他に別のファイルI/Oの手段があったのをご存知ですか?
そうです!FileSystemObject(以下、FSO)を使用した方法です。
前回と同様のコードをFSOを使用して書き上げると以下のようになります。
Dim objFSO As New FileSystemObject
Dim objText As TextStream
Set objText = objFSO.OpenTextFile("D:\TEST.TXT", ForReading, , TristateUseDefault)
Do While Not objText.AtEndOfStream
Text1.Text = Text1.Text & objText.ReadLine & vbCrLf
Loop
objText.Close
Set objText = Nothing
Set objFSO = Nothing
|
実はもうひとつの方法とはこのFSOと非常によく似たFileクラスを使用するというものです。
では実際に私が調査した経緯を説明します。
まずはファイルの入出力ということで(絶対にFileクラスというものがあるというのを予測しながら)FileというキーワードでMSDNを検索してみました。
予想通り、File Class が System.IO Namspace以下に存在します。
次に File
Classのメンバを一覧を開き、このクラスにどんなメンバがあるのか?テキストファイルを開くメソッドはないものか?などと思いながら調べてみると、
「ありました!OpenTextメソッド!」
ここまでくればもらったも同然!早速コーディングしてみることにします。
System.IOへのNamespaceを有効にするために、全回同様、プロジェクトのプロパティダイアログを開き、
System.IO をインポートしてください。
前準備が整いましたのでいよいよファイルの読み込みを記述します。
OpenTextメソッドの構文は以下のようになっています。
Overloads Public Shared Function OpenText(ByVal
path As
String) As StreamReader
Fileクラスの OpenTextメソッドがStreamReaderオブジェクトを返すため、以下のように
StreamReaderオブジェクト変数を定義し、OpenTextを実行します。
Dim reader
As
StreamReader
reader = File.OpenText("D:\TEST.TXT")
次にこのStreamReaderのデータを1行ごとにデータの終わりまで順に読み込みます。
(実はFSOのTextStreamの場合もこのStreamReaderの場合もストリームとして一括してデータを最初から最後まで読み込む事は可能なのですが、今回は1行ごとにデータを読み込むという仕様のもとで話を進めてきましたので割愛します。)
FSOの場合はTextStreamの終わりを検出するプロパティとしてAtEndOfStreamというもの(わかりやすい!)がありましたが、今回も同じようなものがあるのでしょうか?(絶対にあるはずですけど)
MSDNでStreamReaderクラスのすべてのメンバに関する説明を順に見ていきます。(英語です...) すると...。
直接的なものはありませんでしたが、Peekメソッドの説明が
読み取り可能な次の文字を返しますが、その文字は使用されません。
となっており、このメソッドは次に読み込み可能なキャラクタが存在しない場合、戻り値に-1を返すとありますので、何とか使えそうです。
入力ストリームより1行ずつデータを読み込むメソッドはFSOと同様ReadLineメソッドです。
以上で必要な機能は全て満たされました。コーディングしてみると以下のようになります。
Dim reader As StreamReader
reader = File.OpenText("D:\TEST.TXT")
Do While Not reader.Peek() = -1
Text1.Text += reader.ReadLine & Controlchars.CrLf
Loop
reader.Close()
reader = Nothing
|
実行...。
「???」
何だか文字化けしているようです。
早速、MSDNで StreamReader クラスについて調べてみると、どうやら StreamReader
クラスのデフォルトのエンコーディングは UTF-8 のようです。
よって事前に この StreamReader クラスがどのコードページを使用するのか指定する必要がありそうですね。
Dim reader As StreamReader
reader = New StreamReader("D:\TEST.TXT", System.Text.Encoding.Default)
Do While Not reader.Peek() = -1
Text1.Text += reader.ReadLine.ToString & vbCrLf
Loop
reader.Close()
reader = Nothing
|
どうでしょうか?
「ふぅ〜っ!」
ついにというか、やっと正しくテキストを日本語で表示することができるようになりました。
ここで先ほどのコードもそうですが、このコードをご覧になって 「あれれっ!」 と思われた方、よく気づいてくれました!
Do...Loop内でTextプロパティに文字列を追加するコードが
Text1.Text +=
reader.ReadLine & vbCrLf となっています。(C言語みたいですね)
いままでのVBでしたら、
Text1.Text = Text1.Text & reader.ReadLine & vbCrLf
と書くのが常識でした。
VB.NETではこのような記述ができるようになったのもおわかりいただけたかと思います。
もうひとつ書いておきますが、VB.NETでは
Dim A As
Short = 1
といった変数の定義と初期化を一度に記述する事も可能になりました。
[余談]
C言語のような記述も多少可能になったといっても、i++という記述はできません。
こういった場合は i += 1 と記述します。
ちょっと横道にそれてしまいましたが、以上でテキストファイルの読み込みは完了です。
次回はファイルの書き込みを行ってみたいと思います。
今日の収穫
1.ファイルの入出力にはFSOと類似したSystem.IOライブラリのFileクラスが存在する。
2.StreamReader や StreamWrite クラスはデフォルトで UTF-8 エンコードされているため、
事前にコンストラクタ(New)等で コードページ を指定しておくか、TextStream
をEncoding.クラスのConvertメソッドなどで変換する必要がある。
3.演算式 "A = A + B" は "A += B"という記述が可能になった。
4.変数の定義において、初期化を含む記述が可能になった。
(例) Dim A As Short = 1
|