.NET Framework 2.0 コア機能解説 ~ 第 4 回 I/O の機能強化 ~

青柳 臣一

Microsoft MVP for Visual Developer - Visual C#

◆I/Oの機能強化

.NET Framework 2.0 ではさまざまな I/O 機能が強化されています。主要なものをご紹介します。

◆File クラスの新機能

テキストファイルのすべての行を文字列の配列に読み込む場合を考えてみましょう。.NET Framework 1.0、1.1 では StreamReader.ReadLine() メソッドを使用して 1 行ずつ読み込む、または、StreamReader. ReadToEnd() メソッドを使用してファイル全体を読み込み改行で分割するなどという方法が一般的でした。

以下は、ReadLine() メソッドを使用して 1 行ずつすべての行を読み込むコード例です。

◆アクセス制御リストを利用したプログラムサンプル

== C#の例(1.0、1.1)=========================================== 
string[] lines;
using (StreamReader sr = new StreamReader("c:\\test.txt", Encoding.GetEncoding("Shift_JIS")))
{
    ArrayList ary = new ArrayList();
    while (!sr.EndOfStream)
    {
        ary.Add(sr.ReadLine());
    }
    lines = (string[])ary.ToArray(typeof(string));
}
==Visual Basicの例(1.0、1.1)===================================
Dim lines As String()
Dim sr As StreamReader = Nothing
Try
    sr = New StreamReader("c:\test.txt", Encoding.GetEncoding("Shift_JIS"))
    Dim ary As New ArrayList
    While Not sr.EndOfStream
        ary.Add(sr.ReadLine())
    End While
    lines = ary.ToArray(GetType(String))
Finally
    If Not sr Is Nothing Then
        sr.Close()
    End If
End Try
===================================================

上記のコード例は、もちろん .NET Framework 2.0 でもなんの問題も無くコンパイルできますし、実行もできます。また、 2.0 であればジェネリックを使用してList (VB では List(Of String)) としたり、 VB も C# と同様に Using ブロックを使用したりすればもう少し簡潔なコードになるでしょう。
しかし、 .NET Framework 2.0 にはとても便利なメソッドが用意されています。

== C#の例(2.0)=========================================== 
string[] lines = File.ReadAllLines("c:\\test.txt", Encoding.GetEncoding("Shift_JIS"));
==Visual Basicの例(2.0)===================================
Dim lines As String() = File.ReadAllLines("c:\test.txt", Encoding.GetEncoding("Shift_JIS"))
===================================================

このように System.IO.File クラスの ReadAllLines() メソッドは、ファイルをオープンし、すべての内容を文字列の配列に読み込み、ファイルをクローズする、という一連の処理すべてを行ってくれます。

File クラスには他にも便利なメソッドが追加されていますので、主要なものを紹介します。なお、それぞれのメソッドの詳細は MSDN ライブラリでご確認ください。

AppendAllText

ファイルの末尾に文字列を追加します。 Encoding の指定も可能です。

ReadAllBytes

ファイルの内容すべてを Byte の配列として読み込みます。

ReadAllLines

ファイルの内容すべてを文字列の配列として読み込みます。 Encoding の指定も可能です。(上記で紹介)

ReadAllText

ファイルの内容すべてを 1 つの文字列として読み込みます。 Encoding の指定も可能です。

Replace

あるファイルを別のファイルで置き換えます。このときファイルのバックアップも作成します。

WriteAllBytes

ファイルの内容すべてを Byte の配列で置き換えます。

WriteAllLines

ファイルの内容すべてを文字列の配列で置き換えます。 Encoding の指定も可能です。

WriteAllText

ファイルの内容すべてを 1 つの文字列で置き換えます。 Encoding の指定も可能です。

また、 Encrypt() メソッド、 Decrypt() メソッドも追加されています。これらのメソッドはファイルの暗号化・複合化を行います。なお、この暗号化とは NT 以降の Windows OS が標準で持つファイル単位の暗号化機能のことです。

◆DriveInfo クラス

.NET Framework 2.0 には System.IO.DriveInfo クラスが追加されています。このクラスを使うとパソコンに接続されているドライブの情報を簡単に取得することができます。

== C#の例=========================================== 
foreach (DriveInfo drive in DriveInfo.GetDrives())
{
    Console.WriteLine(drive.Name);
    Console.WriteLine("種類: " + drive.DriveType.ToString());
    if (drive.IsReady)
    {
        Console.WriteLine("合計サイズ: " + drive.TotalSize);
        Console.WriteLine("空き領域: " + drive.AvailableFreeSpace);
    }
    Console.WriteLine("==");
}
==Visual Basicの例===================================
For Each drive As DriveInfo In DriveInfo.GetDrives()
    Console.WriteLine(drive.Name)
    Console.WriteLine("種類: " & drive.DriveType.ToString())
    If drive.IsReady Then
        Console.WriteLine("合計サイズ: " & drive.TotalSize)
        Console.WriteLine("空き領域: " & drive.AvailableFreeSpace)
    End If
    Console.WriteLine("==")
Next
===================================================

フロッピーディスクや CD-ROM/DVD ドライブなどのリムーバブルディスクの場合、メディアが入っていない状態で TotalSize プロパティ、 AvailableFreeSpace プロパティなどにアクセスすると例外が発生します。上記のように IsReady プロパティを使用すればドライブの準備ができているかどうかを判定することができます。

また、 「C ドライブの空き容量を取得する」 というようなことも可能です。

== C#の例=========================================== 
DriveInfo cdrive = new DriveInfo("c:");
Console.WriteLine("Cドライブの空き領域: " + cdrive.AvailableFreeSpace);
==Visual Basicの例===================================
Dim cdrive As DriveInfo = New DriveInfo("c:")
Console.WriteLine("Cドライブの空き領域: " & cdrive.AvailableFreeSpace)
===================================================

◆System.IO.Compression 名前空間

.NET Framework 2.0 では圧縮・解凍を行いながら I/O できるストリームが追加されました。それが System.IO.Compression 名前空間の GZipStream クラスと DeflateStream クラスです。それぞれ gzip 形式、deflate 形式の圧縮・解凍が可能です。ここでは GZipStream を紹介します。

(1) 圧縮
それでは、文字列を格納した gzip 圧縮済みのファイルを作成してみましょう。

== C#の例=========================================== 
using (FileStream stm = new FileStream("c:\\test.gz", FileMode.Create))
using (GZipStream gzip = new GZipStream (stm, CompressionMode.Compress))
using (StreamWriter writer = new StreamWriter(gzip, Encoding.GetEncoding("Shift_JIS")))
{
    writer.WriteLine("abcde");
    writer.WriteLine("あいうえお");
}
==Visual Basicの例===================================
Using stm As FileStream = New FileStream("c:\test.gz", FileMode.Create), _
      gzip As GZipStream = New GZipStream(stm, CompressionMode.Compress), _
      writer As StreamWriter = New StreamWriter(gzip, Encoding.GetEncoding("Shift_JIS"))
    writer.WriteLine("abcde")
    writer.WriteLine("あいうえお")
End Using
===================================================

この例では、書き出し先の FileStream を作り、それに圧縮用の GZipStream をかぶせ、さらに StreamWriter をかぶせています。 StreamWriter を使っているのは単に WriteLine() メソッドを使用したかったからです。バイトの配列を書き出すだけでしたら GZipStream にも Write() メソッドがありますから StreamWriter は不要になります。

このように GZipStream は 「圧縮・解凍を行うストリーム」 として実装されていますので、他の Stream 系クラスや StreamWriter/StreamReader などと組み合わせて使うことができます。

なお、 GZipStream はあくまで gzip 形式で圧縮・解凍を行うストリームです。複数のファイルをまとめて圧縮したり、 ZIP ファイル(拡張子 .zip のファイル)を直接扱ったりする機能はありません。もちろん、 gzip 形式をサポートするツールを使用すれば GZipStream で圧縮したファイルの内容を見ることなどはできます。

(2) 解凍

解凍も圧縮と同様に行えます。

== C#の例=========================================== 
using (FileStream stm = new FileStream("c:\\test.gz", FileMode.Open))
using (GZipStream gzip = new GZipStream(stm, CompressionMode.Decompress))
using (StreamReader reader = new StreamReader(gzip, Encoding.GetEncoding("Shift_JIS")))
{
    while (!reader.EndOfStream)
    {
        Console.WriteLine(reader.ReadLine());
    }
}
==Visual Basicの例===================================
Using stm As FileStream = New FileStream("c:\\test.gz", FileMode.Open), _
      gzip As GZipStream = New GZipStream(stm, CompressionMode.Decompress), _
      reader As StreamReader = New StreamReader(gzip, Encoding.GetEncoding("Shift_JIS"))
    While Not reader.EndOfStream
        Console.WriteLine(reader.ReadLine())
    End While
End Using
===================================================

◆参考資料

Page view tracker