質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

1215閲覧

c++ ファイルの分割ロードについて

ssssskkkkk

総合スコア20

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/09/19 02:50

編集2017/09/19 09:33

###ファイルの分割ロードについて
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}

どのようにすれば実現できるのでしょうか。よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coco_bauer

2017/09/19 03:00

どんなファイルを読み込んでいるのかはssssskkkkkさんしか知りませんから、どんな使い方をするのかを知っているのもssssskkkkkさんしか居ません。他の人に判る訳がないと思いませんか?
ssssskkkkk

2017/09/19 09:16

そうですよね、質問を修正したいと思います。
t_obara

2017/09/22 04:27

うまくいかないとは、具体的にどのような動作になったのでしょうか
guest

回答1

0

ベストアンサー

こんにちは。

このコードで最終的にFileクラスのmDataに読み込んだデータが格納されると踏んでいるのですが、そのような理解で合っているのでしょうか。

あっていると思いますが、何をやりたいのかコードから読み取れないのでssssskkkkkさんの期待通りに動作するかどうかは私には分かりません。

実際に走らせて確認するのが良いですよ。走らせるためにはmain()ルーチンが必要ですね。まずはmain()を書きましょう。その過程で様々な疑問を解決できると思います。
分からない部分を「具体的」に質問できるので回答も返ってきやすくなるという意味です。

投稿2017/09/19 07:11

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ssssskkkkk

2017/09/19 09:17

ご指摘ありがとうございます。 実際に走らせてみたのですが、やはりまだ分からない箇所があるので、具体的になるよう、質問を修正したいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問