連載

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

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

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


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

 エンコーディング名を指定したテキスト・ファイルの入出力

 .NET Frameworkクラス・ライブラリを用いてテキスト・ファイルを入出力する際、何も指定しなければUTF-8となる(.NET Frameworkクラス・ライブラリを用いたテキスト・ファイルの入出力を参照)。しかし、もしUTF-8が将来の主流になるとしても、過去に作成したデータ・ファイルを読み出すニーズがなくなるわけではない。クラス・ライブラリを用いても、明示的に使用する文字エンコーディングを指定すれば、UTF-8以外の方法で読み書きすることができる(シフトJISとUTF-8の相違の具体的な相違点については、シフトJISとUTF-8の相違を参照)。例えば、シフトJISで読み書きする場合はリスト3-47のように記述する。

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

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

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

 このサンプル・プログラムが作成したファイルを直接シフトJISで開くと、図3-49のようになる。

●図3-49 リスト3-47の出力ファイルをシフトJISとして開いたところ

 これで、UTF-8ではなく、シフトJISでうまく書き込まれたことが分かるだろう。また、シフトJISで書き込まれたファイルを間違いなく読み込んでいることも分かるだろう。

 ソース・コードの変更点は3点ある。1つは、2行目にSystem.Text名前空間への参照が追加されたことである。この名前空間には、文字エンコーディングを扱うEncodingクラスがある。次の変更点は11行目である。StreamWriterクラスのオブジェクトを作成する際、ファイル名だけでなく、

Encoding.GetEncoding("Shift_JIS")

という指定が追加されている。これは、EncodingクラスにあるGetEncodingメソッドを呼び出すことを意味する。引数の文字列を文字エンコーディングの名前と認識して、それに対応するオブジェクトを得るという意味である。これをStreamWriterクラスに渡すことにより、指定された文字エンコーディングでファイルに書き込むことができる。なお、第2引数にFalseという値が書き込まれているが、これはファイルに追加する機能は使わないことを意味するものである。第2引数を飛ばして第3引数を書くことができないので追加された値だ。第3の変更点は、ソースの22行目にあるが、第2の変更点と同じ情報をStreamReaderクラスに追加したものである。

 さて、GetEncodingメソッドに指定する名前は、何も「Shift_JIS」に限らない。ここには、インターネットの名前の登録機関であるIANA(The Internet Assigned Numbers Authority)に登録されたcharset名が指定可能ということになっている。そのため、主に電子メールの送受信に使われる「ISO-2022-JP」や、主にUNIXワークステーションなどで指定される「EUC-JP」も指定することができる。つまり、Windowsの標準からかけ離れたテキスト・データをVB.NETアプリケーションから読み書きする場合にも、StreamReaderやStreamWriterクラスの利用は有益なのである。このような使い方は、VB 6の入主力ステートメントや、ファイルシステム・オブジェクトでは実現できなかったものである。

 これはちょっと余談気味だが、Encodingクラスは利用頻度が多くないので「Imports System.Text」の手順を省いて、

Encoding.GetEncoding("Shift_JIS")

の代わりに

System.Text.Encoding.GetEncoding("Shift_JIS")

と書いてもよい。また、このメソッドから戻ってくるのはSystem.Text.Encoding型のオブジェクトなので、これを変数に保存しておき、何回も使うことができる。

 リスト3-50は、それを実際に記述してみたサンプル・プログラムである(実行結果はリスト3-48と同じなので特に掲載しない)。

 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 Shift_JIS As System.Text.Encoding
10:     Shift_JIS = System.Text.Encoding.GetEncoding("Shift_JIS")
11:
12:     Dim writer As StreamWriter, reader As StreamReader
13:     writer = New StreamWriter("c:\test.txt", False, Shift_JIS)
14:     writer.Write("Test")
15:     writer.WriteLine(" Data")
16:     writer.WriteLine("テストデータ")
17:     writer.Write("ファイル番号は")
18:     writer.WriteLine("使用していません")
19:     writer.WriteLine("A" & Space(1) & "B" & Space(5) & "C")
20:     writer.WriteLine(True & "," & False)
21:     writer.WriteLine(Today)
22:     writer.Close()
23:
24:     reader = New StreamReader("c:\test.txt", Shift_JIS)
25:     Do
26:       Dim s As String
27:       s = reader.ReadLine()
28:       If s = Nothing Then Exit Do
29:       Trace.WriteLine(s)
30:     Loop
31:     reader.Close()
32:   End Sub
33: End Class
リスト3-50 Encodingオブジェクトの記述方法を変更したプログラム

 シフトJISとUTF-8の相違

 前々項および前項で述べたように、.NET Frameworkクラス・ライブラリを用いてテキスト・ファイルを入出力する際、何も指定しなければUTF-8となる。しかし、エンコーディング名を指定すれば、従来どおりのシフトJISで入出力することもできる。このことから「UTF-8なんてわけの分からないものは嫌だな〜、ちょっと書き足せばむかしどおりのシフトJISになるなら、ずっとそのままでいこうかな〜」と思った人のために、シフトJISにとどまってはいられない事例をひとつお見せしよう。

 1: Imports System.IO
 2:
 3: Public Class Form1
 4:   Inherits System.Windows.Forms.Form
 5:
 6: …Windows フォーム デザイナで生成されたコード…
 7:
 8:   Private Sub EncodingSample(ByVal encodingName As String)
 9:     Dim encoding As System.Text.Encoding
10:     encoding = System.Text.Encoding.GetEncoding(encodingName)
11:
12:     Dim writer As StreamWriter, reader As StreamReader
13:     writer = New StreamWriter("c:\test.txt", False, encoding)
14:     Dim i As Integer
15:     For i = &H4E00 To &H4E0F
16:       writer.Write(ChrW(i))
17:     Next
18:     writer.Close()
19:
20:     reader = New StreamReader("c:\test.txt", encoding)
21:     Do
22:       Dim s As String
23:       s = reader.ReadLine()
24:       If s = Nothing Then Exit Do
25:       Trace.WriteLine(s)
26:     Loop
27:     reader.Close()
28:   End Sub
29:
30:   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
31:     EncodingSample("Shift_JIS")
32:     EncodingSample("UTF-8")
33:   End Sub
34: End Class
リスト3-51 2種類の文字コードで同じ処理を行うプログラム

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

●図3-52 リスト3-51の実行結果

 これは、まったく同じ内容を、まず最初にシフトJISでテキスト・ファイルに書き出して読み込み、次にUTF-8で同じことを行ったものである。出力ウィンドウの最後の2行にその結果が現れていると思うが、上がシフトJISを使用した結果、下がUTF-8による結果である。なお、この結果はシステムにインストールされているフォントやOSの種類によっては同じ結果にならない可能性もあり得る。この2行を見れば、同じ結果にならなかったことが分かるだろう。UTF-8で、日本以外の漢字も含め、すべての文字が漢字として表示されている。これに対して、シフトJISでは、所々“?”記号に化けてしまっている。

 この相違は、表現可能な文字の種類が、UTF-8のほうが多いことによる。言い換えると、現在のWindowsで入力や表示が可能な文字のすべてを、シフトJISでは表現できないことを意味する。日本の漢字に限っても、JIS X 0212補助漢字に相当する文字は、UTF-8では扱えるが、シフトJISでは扱うことができない。これらの文字は、Microsoft Officeなどではすでに使用可能な文字であり、シフトJISでデータを保存する限り、Excelなら保存できる漢字が読者のソフトでは保存できない、というトラブルが起きる可能性がある。十分に注意しよう。


 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