私の現在のプロジェクトでは、さまざまな形式のバイナリファイルがたくさんあります。それらのうちのいくつかは単純なアーカイブとして機能するため、抽出されたファイルデータを他のクラスに渡すための良いアプローチを考え出しています。ここでファイルを分割して他のクラスにデータを渡す
は私の現在のアプローチの簡単な例です:
class Archive {
private:
std::istream &fs;
void Read();
public:
Archive(std::istream &fs); // Calls Read() automatically
~Archive();
const char* Get(int archiveIndex);
size_t GetSize(int archiveIndex);
};
class FileFormat {
private:
std::istream &fs;
void Read();
public:
FileFormat(std::istream &fs); // Calls Read() automatically
~FileFormat();
};
アーカイブクラスは基本的にアーカイブを解析し、char
ポインタに格納されたファイルを読み込みます。
std::ifstream fs("somearchive.arc", std::ios::binary);
Archive arc(fs);
std::istringstream ss(std::string(arc.Get(0), arc.GetSize(0)), std::ios::binary);
FileFormat ff(ss);
(アーカイブ内のいくつかのファイルには、追加のアーカイブが、異なる形式のものであってもよいことに注意してください。)
: がArchive
から最初
FileFormat
ファイルをロードするためには、私は現在、次のコードを使用します
バイナリデータを読むとき、私はこれらのような機能をBinaryReader
クラスを使用します。
BinaryReader::BinaryReader(std::istream &fs) : fs(fs) {
}
char* BinaryReader::ReadBytes(unsigned int n) {
char* buffer = new char[n];
fs.read(buffer, n);
return buffer;
}
unsigned int BinaryReader::ReadUInt32() {
unsigned int buffer;
fs.read((char*)&buffer, sizeof(unsigned int));
return buffer;
}
私は、このアプローチの単純さを好むが、私は現在メモリERの多くに苦しみましたrorsとSIGSEGVsと私はそれがこの方法のためだと思う。一例は、ループ内でアーカイブを繰り返し作成して読み込む場合です。これは多数の反復で動作しますが、しばらくしてから、代わりに迷惑データの読み込みを開始します。このアプローチは(私は私が間違っているの何を聞いて、その場合には)実現可能であるし、そうでない場合場合に
私の質問は、何より良い方法があるのですか?
例えば、あなたの関数からポインタを渡すと、関数名は、そうすることは明白であるようなものである場合を除き、それを削除するために知っているユーザーを期待するトラブルを求めている
あなたはArchiveクラスの実装を表示していません。私はstd :: ios :: binaryでistreamを開きますか? – Benj
私はここで書いたコードでstd :: ios :: binaryを忘れましたが、それは私のバージョンにあります。 istreamはifstreamから構築され、そのストリームは上記のようにstd :: ios :: binaryで開かれます。 – Merigrim