###ファイルの分割ロードについて
c++でファイルの分割ロードを実現したいと考えています。
具体的には、毎フレーム128キロバイトずつ、もしくはまだ読み込めていないサイズの合計が128キロバイト未満であれば、残りサイズを読み込みます。
とある本に書いてあったコードを参考に、以下のようなコードを書いてみました。
###Fileクラス
実際に読み込むファイルのデータを保持しています。
c++
1#ifndef _FILE_H_ 2#define _FILE_H_ 3 4/* 5 6File.h 7 8*/ 9 10#include "Singleton.h" 11#include <string> 12 13using namespace std; 14 15class File { 16 17public: 18 19 bool isReady() const; 20 int size() const; 21 const char* data() const; 22 string fileName() const; 23 24 File(const char* fileName); 25 ~File() {}; 26 27private: 28 29 friend class Loader; 30 31 string mFileName; 32 char* mData; 33 int mSize; 34 35}; 36 37#endif 38 39
c++
1#include "File.h" 2 3/* 4 5File.cpp 6 7*/ 8 9bool File::isReady() const { 10 11 return mData != 0; 12 13} 14 15int File::size() const { 16 17 return mSize; 18 19} 20 21const char* File::data() const { 22 23 return mData; 24 25} 26 27string File::fileName() const { 28 29 return mFileName; 30 31} 32 33File::File(const char* fileName) { 34 35 mFileName = fileName; 36 37 mData = 0; 38 39}
###Loaderクラス
ファイルのロードを行うクラスです。
createFileで読み込みたいファイルのListであるmFilesにファイルの登録を行います。
updateを毎フレーム呼び出し、少しずつファイルを読み込みます。
c++
1 2#ifndef _LOADER_H_ 3#define _LOADER_H_ 4 5/* 6 7Loader.h 8 9*/ 10 11#include "Singleton.h" 12#include "File.h" 13#include <list> 14#include <fstream> 15 16class Loader : public Singleton<Loader> { 17 18public: 19 20 void createFile(File** file, const char* fileName); 21 void destroyFile(const char* fileName); 22 void update(); 23 24private: 25 26 friend class Singleton<Loader>; 27 28 Loader() {} 29 Loader(const Loader& obj) {} 30 void operator=(const Loader& obj) {} 31 ~Loader() {} 32 33 list<File*> mFiles; 34 35 size_t mFileSize; 36 size_t mSeekPosition; 37 ifstream* mStream; 38 File* mCurrentFile; 39 char* mData; 40 41 42}; 43 44#endif 45
c++
1 2#include "Loader.h" 3#include "DEBUG.h" 4 5/* 6 7Loader.cpp 8 9*/ 10 11void Loader::createFile(File** file, const char* fileName) { 12 13 ASSERT((!(*file) && "ポインタはNULLである必要があります")); 14 15 *file = new File(fileName); 16 17 mFiles.push_back(*file); 18 19} 20 21void Loader::destroyFile(const char* fileName) { 22 23 bool isFound = false; 24 25 for (auto itr = mFiles.begin(); itr != mFiles.end(); ++itr) { 26 27 File* file = *itr; 28 29 if (file->mFileName == fileName) { 30 31 delete file; 32 33 file = nullptr; 34 35 mFiles.erase(itr); 36 37 isFound = true; 38 39 break; 40 41 } 42 43 } 44 45 ASSERT((isFound && "見つかりませんでした")); 46 47} 48 49void Loader::update() { 50 51 if (mCurrentFile == nullptr && !mFiles.empty()) { 52 53 auto itr = mFiles.begin(); 54 55 mCurrentFile = *itr; 56 57 mStream = new ifstream(mCurrentFile->mFileName); 58 59 mFileSize = static_cast<size_t>(mStream->seekg(0, fstream::end).tellg()); 60 61 mData = new char[mFileSize]; 62 63 } 64 65 if (mCurrentFile != nullptr) { 66 67 int rest = mFileSize - mSeekPosition; // ファイルサイズ - 現在の読み込み位置で、残りのファイルサイズを取得しています。 68 69 int maxKB = 128 * 1024; 70 71 int size = (rest > maxKB) ? maxKB : rest; 72 73 mStream->seekg(mSeekPosition, fstream::beg); 74 75 mStream->read(mData + mSeekPosition, size); 76 77 mSeekPosition += size; 78 79 if (size == rest) { 80 81 mCurrentFile->mData = mData; 82 mCurrentFile->mSize = mFileSize; 83 84 delete mData; 85 mData = 0; 86 87 mFileSize = mSeekPosition = 0; 88 89 delete mStream; 90 91 mFiles.erase(mFiles.begin()); 92 93 mCurrentFile = nullptr; 94 95 } 96 97 } 98 99} 100
###読み込むファイル
Test.txtというファイルを読み込みます。
今回は、試しにファイルサイズが小さいものを読み込んでいるので、あまり分割する意味はありませんが、実際にはもっと大きいファイルを読み込みたいと考えています。
Test.txt
1TEST 2GAMEPROGRAMING
###実現したいこと
上記のTest.txtを読み込み、標準出力に表示したいと思い、mainを以下のように実装したのですが、
上手くいきませんでした。
c++
1#include "Loader.h" 2#include "File.h" 3#include <iostream> 4#include <string> 5 6using namespace std; 7 8int main(void) { 9 10 File* file = nullptr; 11 12 if (file == nullptr) { 13 14 Loader::shared().createFile(&file, "Test.txt"); // shared()はシングルトンクラスによって提供されている、唯一のインスタスを返すメソッドです。 15 16 } 17 18 while (!file->isReady()) { //isReady()は読み込みが終わっているならばtrueを返すので、読み込みが終わっていない間、回ります。 19 20 Loader::shared().update(); 21 22 } 23 24 string str(file->data()); 25 26 cout << str << endl; 27 28 return 0; 29 30}
どのようにすれば実現できるのでしょうか。よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー