前のページ次のページ上に戻るホーム BREW C++ ライブラリ & GUI フレームワーク & XML ミドルウェア : SophiaFramework UNIVERSE 5.0

17.2. ストレージ

ストレージは、ストリームを使ってファイルやネットワーク、メモリなどへ入出力するクラスです。

表 17.2. ストレージ

クラス名 解説
SFXFile ファイルを操作のためのクラスです。
SFXHTTPConnection HTTP / HTTPS 通信のためのクラスです。
SFXTCPSocket TCP ソケット通信のためのクラスです。
SFXSSLSocket SSL ソケット通信のためのクラスです。
SFXMemory メモリストリーム ( バッファストリーム ) のためのストレージクラスです。
SFXSource BREW インターフェースの ISource からデータを読み込むストリームのためのストレージクラスです。
SFXZIPDecoder gzip を利用した Deflate 圧縮を解凍するためのストレージクラスです。

ストレージの種類によって以下の違いはあるものの、 ストリームによる入出力方法はすべてのストレージについて同じなので、 SophiaFramework UNIVERSE の環境下ではストレージデバイスに依存しない汎用的なプログラミングを実現できます。

表 17.3. ストレージクラスに関する、コールバック関数有り無しとその読み込みと書き込み機能について

コールバック関数なし読み込み コールバック関数あり読み込み コールバック関数なし書き込み コールバック関数あり書き込み
SFXFile ×
SFXHTTPConnection × ×
SFXTCPSocket × ×
SFXSSLSocket × ×
SFXMemory × ×
SFXSource △ (BREW ISource に依存) × ×
SFXZIPDecoder △ (登録したストレージに依存) × ×
[Note] 注意
SFXSource と SFXZIPDecoder は、ソースや登録したストレージの種類によっては、コールバック関数無しの読み込みができません。 例えば、コールバック関数無しで SFXTCPSocket からのデータを読み込む機能はサポートされていないので、 SFXTCPSocket からの GZIP データをコールバック関数無しで SFXZIPDecoder に登録して読み込んで解凍することはできません。

17.2.1. ファイル クラス

SFXFile クラスのインスタンスを作成し、ファイルをオープンします。

ファイルのオープン モードには、読み込みモードと読み書きモードの 2 種類があります。

例 17.21. 初期処理

SFXFile file;

// 読み込みモードでファイルをオープンする
file.OpenReadOnly(SFXPath("/dir1/data.txt"));

// 読み書きモードでファイルをオープンする
file.OpenReadWrite(SFXPath("/dir1/data.txt"));

// ストリームを取得する
file.GetStreamReader(&reader);
file.GetStreamWriter(&writer);

// ストリームを使って読み書きする

例 17.22. 終了処理

// ファイルを閉じる
file.Close();

例 17.23. ファイル入力

SFXFile file;                     // 入力ファイル
SFXAnsiStringStreamReader reader; // ファイル読み込み用ストリーム
SFXAnsiString string;             // 読み込む変数

// 読み込みモードでファイルをオープンする
file.OpenReadOnly(SFXPath("/dir1/data.txt"));

// ファイル読み込み用ストリームを取得する
file.GetStreamReader(&reader);

// データを読み込む
reader.Fetch();

// string 変数にデータを読み込む
reader.ReadSFXAnsiString(&string);

ストリームにはデータ入出力用バッファ(ストリームバッファ)があります。

Fetch 関数は、ストレージ (ファイル) からデータを読み込み、ストリームバッファに格納します。

ReadSFXAnsiString 関数は、ストリームバッファからデータを読み込み、指定した変数に格納します。

[Note] 必要なメモリ サイズ

上記のコードでは、ファイルのサイズと同じサイズのストリームバッファが確保されます。 さらに、string 変数用のメモリもストリームバッファと同じサイズで確保されます。

[Note] データをいくつかのセグメントに分割して読み込む方法

固定長バッファによるファイル入力

例 17.24. ファイル出力

SFXFile file;                     // 出力ファイル
SFXAnsiStringStreamWriter writer; // ファイル書き込み用ストリーム
SFXAnsiString string("abcdefg");  // 書き込む変数

// 読み書きモードでファイルをオープンする
file.OpenReadWrite(SFXPath("/dir1/data.txt"));

// ファイル書き込み用ストリームを取得する
file.GetStreamWriter(&writer);

// string を書き込む
writer.WriteSFXAnsiString(string);

// 実際にファイルにデータを書き込む
writer.Flush();

WriteSFXAnsiString 関数で string 変数のデータをストリームバッファに書き込みます。 Flush 関数は、ストリームバッファのデータをストレージ (ファイル) に書き込みます。

[Caution] フラッシュしないと ...

フラッシュせずにファイルを閉じると、データは書き込まれません。

[Note] ストリームバッファ

上記のコードでは、書き込む文字列と同じサイズのストリームバッファが確保されます。

[Note] データをいくつかのセグメントに分割して書き込む場合

Write 関数でセグメントに分割されたデータをストリームバッファに書き込む度に、 Flush 関数を呼び出してストリームバッファに書き込まれたデータ セグメントを実際にファイルに書き込みます。 そして、書き込むデータ セグメントがなくなるまで Write 関数と Flush 関数を交互に繰り返して呼び出します。

17.2.2. TCP ソケット通信クラス

SFXTCPSocket クラスを使った TCP ソケット通信によるデータ送受信は、 TCP ソケットを作成・オープンし、TCP サーバーに接続してから、 ストリームとコールバック関数を使って以下の手順で行います。

■ 送信

  1. TCP ソケットからデータ送信用ストリームを取得します。
  2. データ送信用ストリームへデータを書き込みます。
  3. 実際にデータを送信し、データ送信完了の通知を受け取るコールバック関数を登録します。
  4. データ送信が完了すると、3. で登録したコールバック関数が呼ばれます。
  5. コールバック関数では、データ送信後の処理を実行します。

■ 受信

  1. TCP ソケットからデータ受信用ストリームを取得します。
  2. 実際にデータを受信し、データ送受信完了の通知を受け取るコールバック関数を登録します。
  3. データ受信が完了すると、2. で登録したコールバック関数が呼ばれます。
  4. コールバック関数では、データ受信用ストリームからデータを読み込みます。

関連情報: ネットワーク : ソケット通信

例 17.25. ストリームを使った TCP ソケット通信

// コールバック関数で使うので、SFXTCPSocket インスタンスはクラスのメンバ変数として定義する
class MyClass {
private:
    SFXTCPSocket _socket;                // SFXTCPSocket インスタンス
    SFXAnsiStringStreamReader  _reader;  // データ受信用ストリーム
    SFXAnsiStringStreamWriter  _writer;  // データ送信用ストリーム
public:
    Void Start(Void);
    XALLBACK_DECLARE_SFXTCPSOCKET(OnConnect)
    XALLBACK_DECLARE_SFXANSISTRINGSTREAMREADER(OnFetch)
    XALLBACK_DECLARE_SFXANSISTRINGSTREAMWRITER(OnFlush)
};

Void MyClass::Start(Void)
{
    // 初期処理
    _socket.Open();
    
    // 接続を開始する ( 接続の完了は、OnConnect 関数に通知される )
    _socket.Connect(SFXSocketAddress("www.example.com:80"), XALLBACK_FUNCTION(OnConnect));
}

// 接続の完了が通知されるコールバック関数
XALLBACK_IMPLEMENT_SFXTCPSOCKET(MyClass, OnConnect, error)
{
    // データ受信用ストリームを取得する
    _socket.GetStreamReader(&_reader);
    
    // データ送信用ストリームを取得する
    _socket.GetStreamWriter(&_writer);
    
    // データを書き込む
    _writer.WriteSFXAnsiString("GET / HTTP/1.1\r\n\r\n");
    
    // 実際にデータを送信する ( データ送信の完了は、OnFlush 関数に通知される )
    _writer.Flush(XALLBACK_FUNCTION(OnFlush));
}

// データ送信の完了が通知されるコールバック関数
XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMWRITER(MyClass, OnFlush, error)
{
    // データの受信

    // データを受信する ( データ受信の完了は、OnFetch 関数に通知される )
    _reader.Fetch(XALLBACK_FUNCTION(OnFetch));

    // ここで _reader.Read を呼び出すとエラーになる
}

// データ受信の完了が通知されるコールバック関数
XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error)
{
    SFXAnsiString string;

    // 受信したデータを string 変数に格納する
    _reader.ReadSFXAnsiString(&string);
}

17.2.3. HTTP 通信クラス

HTTP 通信クラス ( SFXHTTPConnection ) もストリームを使ってデータ送受信できます。

例 17.26. ストリームを使った HTTP 通信

// HTTP 通信に必要な SFXHTTPConnection クラスのインスタンス _http はクラスのメンバ変数として定義する
SFXHTTPConnection _http;

// 初期処理
_http.Open();

// 接続を開始する ( 接続の完了は、OnConnect 関数に通知される )
_http.Connect(SFXSocketAddress("www.example.com:80"), XALLBACK_FUNCTION(OnConnect));

// ...

// 接続を閉じる
_http.Close();

17.2.4. SSL ソケット通信クラス

SFXSSLSocket クラスを使った SSL ソケット通信は、 接続の確立の後にネゴシエートが追加で必要なことを除けば、 TCP ソケット通信と同様の方法でストリームを使ってデータ送受信できます。

TCP ソケットと異なる部分だけを以下に示します。

例 17.27. SSL ソケット通信の方法

// 接続の完了が通知されるコールバック関数
XALLBACK_IMPLEMENT_SFXSSLSOCKET(MyClass, OnConnect, error)
{
    // ネゴシエートするコールバック関数を登録する
    _socket.Negotiate(XALLBACK_FUNCTION(OnNegotiate));
}

// ネゴシエートの完了が通知されるコールバック関数
XALLBACK_IMPLEMENT_SFXSSLSOCKET(MyClass, OnNegotiate, error)
{
    // データ受信用ストリームとデータ送信用ストリームを取得する
    _socket.GetStreamReader(&_reader);
    _socket.GetStreamWriter(&_writer);

    // ストリームを使ってデータを送受信する

    ...

}

17.2.5. メモリ クラス

メモリ クラス ( SFXMemory ) はメモリ( バッファ )を表すストレージクラスです。ストリームを使ったメモリの読み書きに使います。

■ SFXMemory クラスの使用手順

  1. SFXMemory クラスのインスタンスを生成します。
  2. SFXMemory::Open 関数を使ってメモリストレージをオープンします。
  3. SFXMemory::GetStreamReader 関数と SFXMemory::GetStreamWriter 関数を使ってそれぞれメモリ読み込み用ストリームとメモリ書き込み用ストリームを取得します。
  4. ストリームを使ってデータを読み書きします。
  5. ストリームを使い終わったら、SFXMemory::Close 関数を呼び出してリソースを解放します。

例 17.28. 初期処理

SFXMemory memory;

// 空のメモリをオープンする ( サイズは 0 )
memory.Open();

// 指定した値を内部バッファに持つメモリをオープンする
memory.Open("data buffer", 11);

// メモリ読み込み用ストリームとメモリ書き込み用ストリームを取得する
memory.GetStreamReader(&reader);
memory.GetStreamWriter(&writer);

// ストリームに対して読み書きする

...

[Note] 注意
SFXMemory クラスのインスタンスを作成し、メモリをオープンする方法は 2 種類あります。

例 17.29. 終了処理 1

// メモリを閉じる ( 内部バッファは空になる )
memory.Close();

以下のようにして、メモリを閉じるときにその内容を指定した変数に格納できます。

例 17.30. 終了処理 2

SFXBuffer buffer;

// メモリを閉じる ( 内部バッファは buffer にコピーされて空になる )
memory.Close(&buffer);

17.2.6. BREW ISource インターフェースにアクセスするためのクラス

BREW の ISource インターフェースを、SophiaFramework UNIVERSE のストリームからアクセスする場合、 SFXSource を使います。

■ SFXSource クラスの使用手順

  1. SFBSource インターフェースを作成し読み出すストレージを用意します。それから、SFXSource::Open 関数を呼び出してストレージを登録します。
  2. SFXSource::GetStreamReader 関数を使って読み込み用ストリームを取得します。
  3. 取得したストリームを使い、データを読み込みます。ストレージの種類によっては、コールバック関数を使ってデータを読み込みます。
  4. ストリームを使い終わったら、SFXSource::Close 関数を呼び出してリソースを解放します。

例 17.31. 初期処理

// BREW の ISource
SFBSourceSmp brewSource;

SFXSource source;

source.Open(brewSource);

// 読み込み用ストリームを取得する
source.GetStreamReader(&reader);

// reader から読み込む

...

例 17.32. 終了処理

source.Close();

詳細情報 : サンプルコード

17.2.7. gzip 解凍 クラス

SFXZIPDecoder は、SFXFileSFXTCPSocket などのストレージクラスや SFBSourceSFBAStream に格納された gzip による Deflate 圧縮データを解凍するクラスです。

■ SFXZIPDecoder クラスの使用手順

  1. SFXZIPDecoder クラスのインスタンスを生成します。
  2. SFXZIPDecoder::Open 関数を呼び出して、ストレージクラス、SFBAStream クラス、SFBSource クラスの Deflate 圧縮されたデータを登録します。
  3. SFXZIPDecoder::GetStreamReader 関数を使って、入力ストリームを取得します。
  4. 通常の入力ストリームと同様に、解凍されたデータとして取得します。

例 17.33. 初期処理

SFXFile file;
SFXZIPDecoder decoder;
SFXAnsiString string;

// ファイルをオープンする
file.Open(SFXPath("/testdata.tar.gz"));

// ストレージ (ファイル) をデコーダに登録する
// ( SFBSource や SFBAStream クラスのインスタンスも登録できる )
decoder.Open(file);

// 読み込み用ストリームを取得する
decoder.GetStreamReader(&reader);

例 17.34. 終了処理

decoder.Close();
file.Close();

詳細情報 : サンプルコード