連載

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

第8回 ファイル入出力(後編)

(株)ピーデー
川俣 晶
2002/06/08

Page1 Page2 Page3

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

 UTF-8が将来の主流になるとしても、過去に作成したデータ・ファイルを読み出すニーズがなくなるわけではない。クラス・ライブラリを用いても、明示的に使用する文字エンコーディングを指定すれば、UTF-8以外の方法で読み書きすることができる。例えば、シフトJISで読み書きする場合は以下のように記述する。

  1: Imports System.IO
  2: Imports System.Text
  3:
  4: Public Class Form1
  5:   Inherits System.Windows.Forms.Form
  6:
  7: #Region " 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
シフトJISでファイルの入出力を行うVB.NETのサンプル・プログラム2

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

 1: Test Data
 2: テストデータ
 3: ファイル番号は使用していません
 4: A B     C
 5: True,False
 6: 2002/05/03 0:00:00
サンプル・プログラム2の実行結果

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

サンプル・プログラム2の出力ファイルをシフト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クラスの利用は有益なのである。このような使い方は従来の入主力ステートメントや、ファイル・システム・オブジェクトでは実現できなかったものである。

フルネームでエンコーディングを指定する

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

Encoding.GetEncoding("Shift_JIS")

の代わりに

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

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

 以下はそれを実際に記述してみたサンプル・プログラムである。

  1: Imports System.IO
  2:
  3: Public Class Form1
  4:   Inherits System.Windows.Forms.Form
  5:
  6: #Region " 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
Encodingオブジェクトの記述方法を変更したVB.NETのサンプル・プログラム3

 実行結果は前のサンプル・プログラム2と同じなので特に掲載しない。

シフトJISとUTF-8の相違例

 「UTF-8なんて訳の分からないものは嫌だな〜、ちょっと書き足せば昔どおりのシフトJISになるなら、ずっとそのままでいこうかな〜」と思った人のために、シフトJISにとどまってはいられない事例を1つお見せしよう。こんなサンプル・プログラムを用意してみた。

  1: Imports System.IO
  2:
  3: Public Class Form1
  4:   Inherits System.Windows.Forms.Form
  5:
  6: #Region " 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
2種類の文字コードで同じ処理を行うVB.NETのサンプル・プログラム4

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

サンプル・プログラム4の実行結果

 これは、まったく同じ内容を、まず最初にシフト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プログラミング
  第8回 ファイル入出力(後編)
    1..NET Frameworkクラス・ライブラリを用いたテキスト・ファイルの入出力
  2.エンコーディング名を指定したテキスト・ファイルの入出力
    3.テキスト・ファイルの書き込み位置
 
「プロフェッショナル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メールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間