第18回目 ストリーム読み込み

ファイルのストリーム読み込みを作ってみました。
大きなファイルの必要な部分だけを読み込むことができます。
読み込みバッファには第17回目で作ったリングバッファを使用しています。
読み込みにはスレッドを使用してメインスレッドとは非同期でファイルを読み込みします。
また複数のファイルを同時に読み込むことができます。
そのためBGM演奏中にファイルを読み込むと言った事が可能になります。
WindowsやMacOSXの場合は何もしなくてもOS側で同等のことができるようになっているため必要ない機能かもしれません(笑)

動作環境

Windows版はVisualStudio.NET2003用でWin32アプリケーションプロジェクト。
WindowsXP SP2で動作確認。
MacOSX版はXcode3.0のCommandLineUtilityのC++Toolプロジェクト。
IntelOSX10.5.5で動作確認。
MacOSX版の実行ファイルはありません。
CommandLineUtilityのC++Toolプロジェクトでは各OSやCPUで
実行ファイルが変わってしまうので配布は難しいと判断しました。

操作方法

Windows版はフルキーの1,2,3でファイルの読み込み開始。
4,5,6で1,2,3に対応したファイルの読み込み停止。
MacOSX版は下記のStreamクラス使用例と同じものが入っているため
サンプルプログラムをキーボードで操作することはできません。

実行画面 (Windows版)

stream_sample2.png

Streamクラスメンバ

Streamクラスはstandard.h、ringbuffer.cpp/hpp、stream.cpp/hppの5つのファイルから構成されています。
ringbufferは前回作ったものではメモリが足りなくなることが多かったのでnewの変わりにVirtualAllocを使用しました。(Windows専用)
MacOSX版ではmallocを使用しました。

bool Create(int32_t streamcount, size_t streambuffersize, size_t minimumreadsize, size_t maximumreadsize);

クラスの初期化。CD/DVD-ROMの時はminimumreadsizeを2048の倍数に設定すると効率が良くなる(かも)。

bool Release(void);

クラスリリース

int32_t Open(LPCTSTR filepath);

読み込みファイルを開く

bool Close(int32_t handle);

ファイルをクローズ

bool Start(int32_t handle);

読み込み開始

bool Stop(int32_t handle);

読み込み停止

bool Seek(size_t position, int32_t handle);

ファイル位置設定

size_t Tell(int32_t handle);

ファイル位置取得

int32_t GetStatus(int32_t handle);

ステータス取得
Stream::STATUS_READY準備完了
Stream::STATUS_END読み込み終了(ファイルの終わりに来た)
Stream::STATUS_BUSY読み込み中
Stream::STATUS_STOP読み込み停止中
Stream::STATUS_ERRORエラー発生

size_t GetReadableSize(int32_t handle);

読み込み可能なバッファのサイズを取得

bool Read(void* buffer, size_t size, int32_t handle);

バッファ読み込み

Streamクラス使用例

1.binをただ読み込むだけのプログラム。
サンプルプログラムとは関係ありません。

Windows版 (VisualStudio.NET2003)

#include <windows.h>
#include "standard.h"
#include "stream.hpp"
int _tmain(int argc, _TCHAR* argv[])
{
	Stream stream;
	int32_t handle;
	stream.Create(1, 1024 * 16, 1, 1024 * 16);
	handle = stream.Open(_T("1.bin"));
	if(handle == 0)
	{
		return(-1);
	}
	stream.Start(handle);
	while(1)
	{
		size_t readablesize;
		readablesize = stream.GetReadableSize(handle);
		if(readablesize)
		{
			char* buffer;
			buffer = new char[readablesize];
			stream.Read(buffer, readablesize, handle);
			// bufferにreadablesizeバイトのデータが入る
			// ここでbufferに読み込まれたデータを処理する
			delete [] buffer;
		}
		if(stream.GetStatus(handle) == Stream::STATUS_END)
		{
			break;
		}
	}
	stream.Release();
	return 0;
}

MacOSX版 (Xcode3.0)

#include "standard.h"
#include "stream.hpp"
int main(int argc, char* argv[])
{
	Stream stream;
	int32_t handle;
	stream.Create(1, 1024 * 16, 1, 1024 * 16);
	handle = stream.Open("1.bin");
	if(handle == 0)
	{
		return;
	}
	stream.Start(handle);
	while(1)
	{
		size_t readablesize;
		readablesize = stream.GetReadableSize(handle);
		if(readablesize)
		{
			char* buffer;
			buffer = new char[readablesize];
			stream.Read(buffer, readablesize, handle);
			// bufferにreadablesizeバイトのデータが入る
			// ここでbufferに読み込まれたデータを処理する
			delete [] buffer;
		}
		if(stream.GetStatus(handle) == Stream::STATUS_END)
		{
			break;
		}
	}
	stream.Release();
	return 0;
}

ダウンロード

実行ファイル

(Windows版)

filestream_sample2_windows_20090801.zip

(MacOSX版) なし

ソースファイル

(Windows版)

filestream_sample2_windows_source_20090801.zip

(MacOSX版)

filestream_sample_osx_source_20090823.zip

前に戻る?


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS