2012-08-29 29 views
6

我試圖加載一個名爲POSDATA.GAMEDATA的逗號分隔文件。我在互聯網上查了幾個地方,結果我需要做一些調整和/或不同的課程。使用COCOS2D-X的文件I/O

我試過使用ifstream。但是,它無法打開文件。 Xcode 4.3.2似乎無法找到我的POSDATA.GAMEDATA文件。我也嘗試使用ofstream來製作文件,但是當我在兩種情況下都使用open()時,文件未打開。

我的代碼是這樣的:

using namespace std; 
void FileLoader::loadFile(string p_WhichFile) { 
    // Local Variables 
    string thisLine; 

    // Open POSDATA.GAMEDATA 
    ifstream dataStream; 
    dataStream.open(p_WhichFile.c_str()); 

    // Check if file is opened 
    if (!dataStream) { 
     cerr << "[ ERROR ] Cannot load file:" << p_WhichFile.c_str() << endl; 
     exit(1); 
    } 

    // Get lines of strings 
    while (getline(dataStream, thisLine)) { 
     fileContents.push_back(thisLine); // fileContents is a vector<string> object 
    } 

    dataStream.close(); 
    cout << "[ NOTICE ] Finished reading file" << p_WhichFile << endl; 
} 

我見過CCFileUtils但我似乎無法得到如何使用它。

編輯:我試過提供絕對路徑(/Users/LanceGray/Documents/LanceDev/COCOS2DX/cocos2dx/TestGame/Data/POSDATA.GAMEDATA),它工作。但是,我不能這樣做,因爲遊戲應該用於iOS設備和Android,所以每個設備上的路徑並不總是相同的。任何幫助將grealy表示讚賞。

+0

你正在做它在Android或iOS?如果android或者你打算支持兩者,我想你最好使用CCFileUtils來避免進入zip庫。另一方面,如果iOS,你可以使用fopen。我對ifstream不是很熟悉,不能幫得太多。 –

+0

它應該適用於iOS和Android。你能舉一個關於如何使用'CCFileUtils'和'fopen'的小例子嗎?在此期間我會盡力尋找他們。 – alxcyl

回答

16

我用CCFileUtils()::sharedFileUtils() -> fullPathFromRelativePath("POSDATA.GAMEDATA");

更詳細的解釋工作:

  1. 添加您在本項目通過轉到項目樹在左,Right-click -> Add Files需要的文件。我所做的是我在ResourcesClasses文件夾的同一級別添加了一個名爲Data的新文件夾,並將我的POSDATA.GAMEDATA文件放在那裏。在Xcode中,我添加了一個新組,並將該文件添加到該組中。
  2. 然後我用ifstream打開文件。
  3. 打開文件時,使用CCFileUtils()::sharedFileUtils() -> fullPathFromRelativePath()來獲取文件的絕對路徑。提供fullPathFromRelativePath()上的文件名作爲參數。
  4. 嘗試運行它,它應該工作正常。

一個小例子:

// FileReader.h 
#include "cocos2d.h" 

using namespace std; 
using namespace cocos2d; 

class FileReader { 
private: 
    vector<string> mFileContents; 

public: 
    FileReader(string pFileName, char pMode = 'r'); 
}; 

// FileReader.cpp 
#include "FileReader.h" 
#include <fstream> 
#include "cocos2d.h" 

using namespace cocos2d; 
using namespace std; 

FileReader::FileReader(string pFileName, char pMode) { 
    // Create input file stream 
    ifstream inputStream; 
    string thisLine; 

    // Open file 
    inputStream.open(CCFileUtils()::sharedFileUtils() -> fullPathFromRelativePath(pFileName).c_str()); 

    // Check if it is open 
    if (!inputStream.is_open()) { 
     cerr << "[ ERROR ] Cannot open file: " << pFileName.c_str() << endl; 
     exit(1); 
    } 

    while (getline(inputStream, thisLine)) { 
     // Put all lines in vector 
     mFileContents.push_back(thisLine); 
    } 

    inputStream.close(); 
    cout << "[ NOTICE ] Finished opening file: " << pFileName.c_str() << endl; 
} 

該類將加載一個文件名爲pFileName並將其放置在它的成員變量mFileContents。 (請注意,它應該有一個public get功能像vector<string> getFileContents()訪問mFileContents因爲它是private

編輯:上述樣品將在iOS上運行,但是,它不會在Android設備上。所以要解決這個問題,不要使用ifstream,而應使用CCFileUtils::sharedUtils() -> getFileData()。結合CCFileUtils::sharedUtils() -> fullPathFromRelativePath(),我們將能夠實現我們閱讀可在iOS和Android上運行的純文本文件的目標。

FileReader類將被這樣的:

// FileReader.cpp 
#include "FileReader.h" 
#include <fstream> 
#include "cocos2d.h" 

using namespace cocos2d; 
using namespace std; 

FileReader::FileReader(string pFileName, char pMode) { 
    // Initialize variables needed 
    unsigned long fileSize = 0; 
    unsigned char * fileContents = NULL; 
    string thisLine, result, fullPath, contents; 

    // Get absolute path of file 
    fullPath = CCFileUtils::sharedFileUtils() -> fullPathFromRelativePath(pFileName.c_str()); 

    // Get data of file 
    fileContents = CCFileUtils::sharedFileUtils() -> getFileData(fullPath.c_str() , "r", &fileSize); 
    contents.append((char *) fileContents); 

    // Create a string stream so that we can use getline() on it 
    istringstream fileStringStream(contents); 

    // Get file contents line by line 
    while (getline(fileStringStream, thisLine)) { 
     // Put all lines in vector 
     mFileContents.push_back(thisLine); 
    } 

    // After this, mFileContents will have an extra entry and will have the value '\x04'. 
    // We should remove this by popping it out the vector. 
    mFileContents.pop_back(); 

    // Delete buffer created by fileContents. This part is required. 
    if (fileContents) { 
     delete[ ] fileContents; 
     fileContents = NULL; 
    } 

    // For testing purposes 
    cout << "[ NOTICE ] Finished opening file: " << pFileName.c_str() << endl; 
} 
+0

如果你在android上有一個巨大的數據文件,並且無法用getFileData()讀取整個文件,該怎麼辦?這將是很好,有更直接的訪問...像fseek – Cristi

2
// For versions less than v2.0.1 
// The version I am using is 0.12.0 
unsigned long fileSize = 0; 
char* pBuffer = CCFileUltils::getFileData("relative_path","r",&fileSize); 
CCLOG("Data is %s",pBuffer); 
+0

感謝您的幫助。不過,我已經通過使用'CCFileUtils'工作。 – alxcyl

+0

我試過使用'getFileData()',但是我得到一個錯誤,說'斷言失敗:(pszFileName!= __null && pSize!= __null && pszMode!= __null),函數getFileData,文件CCFileUtils.mm,第450行。 'I像這樣使用它:'無符號字符* posdataLoc = CCFileUtils :: sharedFileUtils() - > getFileData(「POSDATA.GAMEDATA」,「r」,0);' – alxcyl

+0

我現在正在'getFileData()'工作。當我在控制檯上看到它時,它會在最後顯示額外的隨機字符。奇怪的。 – alxcyl