バイナリ・データ(=テキスト以外のデータ)をネットワークなどから読み込んで処理したい場合、通常はストリームからバイナリ・データを読み込み、それをバイト配列に格納することになる。本稿では、その手順について解説する。
MemoryStreamクラスによるバッファリング
ストリームからデータを読み込む際、あらかじめデータ全体の長さが分かっていれば、そのサイズのバイト配列を最初に作成し、データを順に読み込んでいくだけでよいが、すべてのストリームで事前にサイズが分かるわけではない(Streamクラス(System.IO名前空間)のすべての派生クラスがLengthプロパティをサポートしているわけではない)。
このため、ストリームから少しずつデータを読み込みながらメモリ上に保存していき、最後にデータ全体をバイト配列に変換するというのが一般的な手順だ。
メモリ上に少しずつデータをため込んでいくような処理には、MemoryStreamクラス(System.IO名前空間)が使える。これはメモリ領域をストリームとして扱うクラスで、Writeメソッドによりバイナリ・データの書き込みが行え、そのメモリ領域は必要に応じて自動的に拡張される。また、ToArrayメソッドにより、メモリ領域のデータをバイト配列として取得できる。
以下のサンプル・プログラム内のReadBinaryDataメソッドは、MemoryStreamクラスを利用してストリームからバイナリ・データを読み込み、それをバイト配列として返す処理を記述した例である。MemoryStreamクラスのWriteメソッドの引数には、メモリ・ストリームに書き込むバイト配列、そのバイト配列内の開始位置、書き込むバイト数を指定する。
// binaryread.cs
using System;
using System.IO;
using System.Net;
public class BinaryRead {
  // ストリームからデータを読み込み、バイト配列に格納
  static public byte[] ReadBinaryData(Stream st) {
    byte[] buf = new byte[32768]; // 一時バッファ
    using (MemoryStream ms = new MemoryStream()) {
      while (true) {
        // ストリームから一時バッファに読み込む
        int read = st.Read(buf, 0, buf.Length);
        if (read > 0) {
          // 一時バッファの内容をメモリ・ストリームに書き込む
          ms.Write(buf, 0, read);
        } else {
          break;
        }
      }
      // メモリ・ストリームの内容をバイト配列に格納
      return ms.ToArray();
    }
  }
  static void Main() {
    string url
      = "http://atmarkit.tech/fdotnet/images/fdotnet_m.gif";
    byte[] data;
    WebRequest req = WebRequest.Create(url);
    using (WebResponse res = req.GetResponse()) {
      using (Stream st = res.GetResponseStream()) {
        data = ReadBinaryData(st);
      }
      File.WriteAllBytes("test.gif", data);
    }
  }
}
// コンパイル方法:csc binaryread.cs
' binaryread.vb
Imports System.IO
Imports System.Net
Class Program
  ' ストリームからデータを読み込み、バイト配列に格納
  Shared Public Function ReadBinaryData(ByVal st As Stream) As Byte()
    Dim buf(32768) As Byte ' 一時バッファ
    Using ms As New MemoryStream()
      While (True)
        ' ストリームから一時バッファに読み込む
        Dim read As Integer = st.Read(buf, 0, buf.Length)
        If read > 0 Then
          ' 一時バッファの内容をメモリ・ストリームに書き込む
          ms.Write(buf, 0, read)
        Else
          Exit While
        End If
      End While
      ' メモリ・ストリームの内容をバイト配列に格納
      Return ms.ToArray()
    End Using
  End Function
  Shared Sub Main()
    Dim url As String _
      = "http://atmarkit.tech/fdotnet/images/fdotnet_m.gif"
    Dim data As Byte()
    Dim req As WebRequest = WebRequest.Create(url)
    Using res As WebResponse = req.GetResponse()
      Using st As Stream = res.GetResponseStream()
        data = ReadBinaryData(st)
      End Using
    End Using
    File.WriteAllBytes("test.gif", data)
  End Sub
End Class
' コンパイル方法:csc binaryread.cs
このサンプル・プログラムのMainメソッドでは、Web上の画像に対するストリームを開き、そこからReadBinaryDataメソッドにより画像データをバイト配列に読み込み、最後にファイル(test.gif)に出力している。
カテゴリ:クラス・ライブラリ 処理対象:バイナリ・ファイル
使用ライブラリ:Streamクラス(System.IO名前空間)
使用ライブラリ:MemoryStreamクラス(System.IO名前空間) 
Copyright© Digital Advantage Corp. All Rights Reserved.

