連載

改訂版
プロフェッショナルVB.NETプログラミング

Chapter 03 ステートメントの変化

株式会社ピーデー 川俣 晶
2004/03/17


 本記事は、(株)技術評論社が発行する書籍『VB6プログラマーのための入門 Visual Basic .NET 独習講座』の一部分を許可を得て転載したものです。同書籍に関する詳しい情報については、本記事の最後に掲載しています。

 参照を使ったファイルシステム・オブジェクトの利用

 前節のファイルシステム・オブジェクトを用いたテキスト・ファイルの入出力で、CreateObject関数を用いてファイルシステム・オブジェクトを使用する方法を解説したが、同じ機能を利用する別の方法がある。それは、参照を追加する方法である。

 VB 6では、プロジェクトに「Microsoft Scripting Runtime」を参照に追加した状態で、以下のサンプル・ソースを実行できる。

 1: Private Sub Form_Load()
 2:   Dim fs As Scripting.FileSystemObject
 3:   Dim rfile As Scripting.TextStream, wfile As Scripting.TextStream
 4:   Set fs = New Scripting.FileSystemObject
 5:   Set wfile = fs.CreateTextFile("c:\test.txt", True)
 6:   wfile.Write "Test"
 7:   wfile.WriteLine " Data"
 8:   wfile.WriteLine "テストデータ"
 9:   wfile.Write "ファイル番号は"
10:   wfile.WriteLine "使用していません"
11:   wfile.WriteLine "A" & Space(1) & "B" & Space(5) & "C"
12:   wfile.WriteLine True & "," & False
13:   wfile.WriteLine Today
14:   wfile.Close
15:
16:   Set rfile = fs.OpenTextFile("c:\test.txt", Scripting.IOMode.ForReading)
17:   Dim s As String
18:   While Not rfile.AtEndOfStream
19:     s = rfile.ReadLine
20:     Debug.Print s
21:   Wend
22:   rfile.Close
23: End Sub
リスト3-37 プロジェクトの参照追加により、ファイルシステム・オブジェクトを利用したプログラム

 これを実行すると以下のようになる。

1: Test Data
2: テストデータ
3: ファイル番号は使用していません
4: A B   C
5: True,False
リスト3-38 リスト3-37の実行結果

 さて、これと同じことをVB.NETでやろうとすると、少々手順が違うので説明しよう。まず、[プロジェクト]のメニューから[参照の追加]を選ぶ。そして[参照の追加]ダイアログボックスで[COM]タブを選ぶ。VB.NETでは参照する対象がCOMオブジェクト以外にも存在するので、必ず[COM]を選ばなければならない。そして、リストから「Microsoft Scripting Runtime」を探し、発見したら[選択]ボタンを押す。

●図3-39 [参照の追加]ダイアログボックス

 そして、ダイアログボックス下部の[選択されたコンポーネント]のリストに、選択した名前が確かにあることを確認してから[OK]ボタンを押す。

 確かに参照が追加されたかどうかを確認するには、オブジェクトブラウザを使用する。オブジェクトブラウザは、[表示]-[オブジェクトブラウザ]で(Visual Studio 2002の場合は、[表示]-[その他のウィンドウ]-[オブジェクトブラウザ]で)表示することができる。

●図3-40 オブジェクトブラウザの表示

 上記のようにInterop.Scriptingという参照が見つかれば、確かに追加されている。

 この参照を用いてVB.NETで実行可能なソースを記述したものがリスト3-41である。

 1: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 2:   Dim fs As Scripting.FileSystemObject
 3:   Dim rfile As Scripting.TextStream, wfile As Scripting.TextStream
 4:   fs = New Scripting.FileSystemObject()
 5:   wfile = fs.CreateTextFile("c:\test.txt", True)
 6:   wfile.Write("Test")
 7:   wfile.WriteLine(" Data")
 8:   wfile.WriteLine("テストデータ")
 9:   wfile.Write("ファイル番号は")
10:   wfile.WriteLine("使用していません")
11:   wfile.WriteLine("A" & Space(1) & "B" & Space(5) & "C")
12:   wfile.WriteLine(True & "," & False)
13:   wfile.WriteLine(Today)
14:   wfile.Close()
15:
16:   rfile = fs.OpenTextFile("c:\test.txt", Scripting.IOMode.ForReading)
17:   Dim s As String
18:   While Not rfile.AtEndOfStream
19:     s = rfile.ReadLine
20:     Trace.WriteLine(s)
21:   End While
22:   rfile.Close()
23: End Sub
リスト3-41 ファイルシステム・オブジェクトを利用したVB.NETのプログラム

 これを実行すると以下のようになる。

1: Test Data
2: テストデータ
3: ファイル番号は使用していません
4: A B   C
5: True,False
6: 2002/04/25
リスト3-42 リスト3-41の実行結果

 見てのとおり、これもほとんど同じソースであることが分かる。ファイルシステム・オブジェクトを用いたテキスト・ファイルの入出力で説明している小さな相違を別にすれば、ほとんど同じようにソースを記述できるといえる。しかし、見た目はそっくりでも、油断はできない。というのは、実行ファイルが生成されるディレクトリを見ると分かるのだが、「Interop.Scripting.dll」というファイルが生成されている。これは、指定したCOMオブジェクト(ファイルシステム・オブジェクトを含むモジュール)のラッパークラス(Wrapper Class)である。VB 6では、直接COMオブジェクトにアクセスしていたが、VB.NETではこのラッパークラスを経由して、COMオブジェクトにアクセスしているのである。実行時には、このファイルも必ず必要となる。

 なお、CreateObjectを使用した場合はまた状況が変わる。この場合、COMオブジェクトへのアクセスは実行時に処理されるので、ラッパー・オブジェクトのDLLファイルは生成されない。


.NET Frameworkクラス・ライブラリを用いたテキスト・ファイルの入出力

 本連載では、ファイル入出力を行う方法として、入出力ステートメント(VB.NETではVB専用関数)を用いる方法と、ファイルシステム・オブジェクトを使用する方法を扱っている(それぞれ、ステートメントを用いたテキスト・ファイルの入出力ファイルシステム・オブジェクトを用いたテキスト・ファイルの入出力を参照)が、それとは別に、.NET Frameworkのクラス・ライブラリを用いる方法がある。それらの解説に含まれるサンプル・ソースと同様の内容を、.NET Frameworkクラス・ライブラリを用いて記述した例を以下に示す。

 1: Imports System.IO
 2:
 3: Public Class Form1
 4:   Inherits System.Windows.Forms.Form
 5:
 6: …Windows フォーム デザイナで生成されたコード…
 7:
 8:   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 9:     Dim writer As StreamWriter, reader As StreamReader
10:     writer = New StreamWriter("c:\test.txt")
11:     writer.Write("Test")
12:     writer.WriteLine(" Data")
13:     writer.WriteLine("テストデータ")
14:     writer.Write("ファイル番号は")
15:     writer.WriteLine("使用していません")
16:     writer.WriteLine("A" & Space(1) & "B" & Space(5) & "C")
17:     writer.WriteLine(True & "," & False)
18:     writer.WriteLine(Today)
19:     writer.Close()
20:
21:     reader = New StreamReader("c:\test.txt")
22:     Do
23:       Dim s As String
24:       s = reader.ReadLine()
25:       If s = Nothing Then Exit Do
26:       Trace.WriteLine(s)
27:     Loop
28:     reader.Close()
29:   End Sub
30: End Class
リスト3-43 .NET Frameworkのクラス・ライブラリを用いてファイル入出力を行うプログラム

 これを実行すると以下のようになる。

1: Test Data
2: テストデータ
3: ファイル番号は使用していません
4: A B     C
5: True,False
6: 2002/05/03 0:00:00
リスト3-44 リスト3-43の実行結果

 ソース・コードを説明しよう。まず、1行目で“Imports System.IO”としているのは、クラス・ライブラリにある多数のクラスの中で、「System.IO」という名前空間に属するクラスを、前置きなしにソース中に記述するという意図を指示するものである(デフォルトの名前空間を指定するImportsステートメントを参照)。

 さて、実際に、この名前空間に含まれているStreamWriterクラスと、StreamReaderクラスをこのソースでは利用している。この2つは、9行目のDimステートメントで普通のVB.NETのクラスのように利用しているが、クラス・ライブラリ内のクラスも、VB.NETで記述したクラスも、機能的に同等なので、同じようなものとして扱って問題ない。

 StreamWriterクラスは、ファイルなどにテキスト・データを出力するために使用されるStreamReaderクラスはファイルなどからテキスト・データを入力するために使用される。どちらもオブジェクトをNewキーワードで生成するときに、ファイル名を指定してやると、それを対象として機能する。Newキーワードで生成するときにはほかにも多くの指定が可能だが、機能が多いので、ここでは最もシンプルな使い方に限って説明を続ける。そして、StreamWriterクラスは、データを文字列として出力するWriteメソッドと、出力後に改行するWriteLineメソッドなどを持つ。SreamReaderクラスは、テキスト・ファイルから1行入力するReadLineメソッドなどを持つ。どちらのクラスもファイルを閉じるCloseメソッドを持っている。これらを使うことで、テキスト・ファイルの入出力が実現できる。

 WriteとWriteLineメソッドは、任意のオブジェクトを引数に記述できるが、これらは自動的に文字列に変換されて出力される。ReadLineメソッドは、ファイルの最後を越えて読み出そうとすると、Nothing値を返してくるので、これでファイルの末尾を判定することができる。

 さて、実行結果を見ると、うまく動作しているように見える。だが、このプログラムが作成したデータ・ファイルをテキスト・エディタ(秀丸など)で開いてみると、そんな単純な話ではないことが分かる分かるだろう。以下は秀丸で開いてみた場合である(設定によってはこれと異なる結果になる可能性もある)。

●図3-45 リスト3-43が出力したデータ・ファイルをテキスト・エディタで開いたところ

 見てのとおり、日本語の文字がすべて化けてしまっている。その理由は、.NET Frameworkのクラス・ライブラリでは、何も指定しなければ自動的に文字エンコーディングとして「UTF-8」が使用されるという仕様による。従来のVB 6や、VB.NETのVB専用関数、ファイルシステム・オブジェクトなどは、何も指定しなければ、その環境のデフォルト、日本では通常「シフトJIS」を使用することになっている。

 日本では、文字は何もかもシフトJISで記述されていると思い込んでいるプログラマーも多いが、実際には世の中に多くの種類の表現方法(エンコーディング)が存在し、それらは相互に互換性がない。そして、そのような互換性のない多くの方法が存在することはデメリットが大きいため、インターネットを中心にUTF-8に統一していこうという動きがある。.NET Frameworkは、まさにその最も先進的な動きを自ら取り込んだ新しいソフトであるため、デフォルトはUTF-8となっている。

 シフトJISの時代には、日本語対応のパソコンで作成したデータを他国に持っていくと文字化けしてしまうという事態も起きたが、UTF-8を用いれば、日本語フォントがないために表示できない事態はあるかもしれないが、文字の種類を誤って判断されることはなくなるため、システムが別の文字と誤認する危険はなくなる。

 このことから当然予測できるように、秀丸のようなテキストエディタでこのファイルを正しく開くには、文字コードとしてUTF-8を指定して開けばよい。

●図3-46 文字コードとして“UTF-8”を指定してデータ・ファイルを開いたところ

 これからは、UTF-8が主流になっていくことは間違いなく、VB.NETで記述されたアプリケーションソフトによって出力されるファイルがUTF-8で記述されていることも珍しくはなくなるだろう。

 UTF-8のことを詳しく知りたいという方には、以下の本を推薦しておく。

Unicode標準入門
Tony Graham著/関口正裕 監修/乾和志、海老塚徹 訳
ISBN4-7981-0030-7/定価 3800円/翔泳社発行

 しかし、互換性のため、シフトJISで読み書きしなければならない、という状況もあるだろう。UTF-8以外のエンコーディングを指定して入出力する方法は、エンコーディング名を指定したテキスト・ファイルの入出力を、シフトJISとUTF-8の相違の具体的な相違点については、シフトJISとUTF-8の相違を参照してほしい。


 INDEX
  [連載] 改訂版 プロフェッショナルVB.NETプログラミング
  Chapter 03 ステートメントの変化
    1.WendをEnd Whileに書き換える/プロシージャ脱出とReturnステートメント/関数の戻り値とReturnステートメント
    2.読み取り専用変数/複合代入ステートメント/ Staticの付いたプロシージャ/ランダム・ファイルとVBFixedString属性
    3.ステートメントを用いたテキスト・ファイルの入出力/ファイルシステム・オブジェクトを用いたテキスト・ファイルの入出力
  4.参照を使ったファイルシステム・オブジェクトの利用/ .NET Frameworkクラス・ライブラリを用いたテキスト・ファイルの入出力
    5.エンコーディング名を指定したテキスト・ファイルの入出力/シフトJISとUTF-8の相違
    6.UTF-8によるファイル出力時の文字列サイズの変化/テキスト・ファイルの書き込み位置/さまざまなファイル入出力手段の中でどれを選ぶべきか
    7.Debug.Assertメソッドの移行
    8.TraceクラスとDebugクラスの相違/条件式抜きで必ず停止させるFailメソッド/マルチスレッドを同期するSyncLockステートメント/古い制御構造 On…GoToとOn…GoSub
 
「改訂版 プロフェッショナルVB.NETプログラミング 」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH