2012-08-29 13 views
6

Estoy intentando cargar un archivo separado por comas llamado POSDATA.GAMEDATA. He buscado varios sitios en Internet y resulta que necesito hacer algunos ajustes y/o una clase diferente.Archivo de E/S con COCOS2D-X

Intenté usar ifstream. Sin embargo, no puede abrir el archivo. Xcode 4.3.2 parece que no puede encontrar mi archivo POSDATA.GAMEDATA. También intenté hacer el archivo usando ofstream pero cuando uso open() en ambos casos, el archivo no se abre.

Mi código es algo como esto:

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; 
} 

que he visto CCFileUtils pero me parece que no puede llegar a usarlo.

EDIT: He intentado suministrar la ruta absoluta (/Users/LanceGray/Documents/LanceDev/COCOS2DX/cocos2dx/TestGame/Data/POSDATA.GAMEDATA) y funcionó. Sin embargo, no puedo hacer esto porque se supone que el juego se usa en dispositivos iOS y Android, por lo que la ruta no siempre es la misma en cada dispositivo. Cualquier ayuda será muy apreciada.

+0

lo está haciendo en Android o iOS? si android o si está planeando admitir ambas, supongo que será mejor que use CCFileUtils para evitar entrar en la librería zip. Por otro lado, si iOS, puedes usar fopen. No estoy muy familiarizado con ifstream, no puedo ayudar mucho. –

+0

Se supone que es para iOS y Android. ¿Puedes dar un pequeño ejemplo sobre cómo usar 'CCFileUtils' y' fopen'? Trataré de buscarlos mientras tanto. – alxcyl

Respuesta

16

me dieron trabajo mediante el uso de CCFileUtils()::sharedFileUtils() -> fullPathFromRelativePath("POSDATA.GAMEDATA");

Una explicación más detallada:

  1. Añadir los archivos que necesita en el Proyecto yendo al Árbol de proyectos a la izquierda y Right-click -> Add Files. Lo que hice fue agregar una nueva carpeta llamada Data en el mismo nivel que las carpetas Resources y Classes y colocar allí mi archivo POSDATA.GAMEDATA. En Xcode, agregué un nuevo grupo y agregué ese archivo en ese grupo.
  2. Luego usé ifstream para abrir el archivo.
  3. Al abrir el archivo, use CCFileUtils()::sharedFileUtils() -> fullPathFromRelativePath() para obtener la ruta absoluta del archivo. Proporcione el nombre del archivo en fullPathFromRelativePath() como argumento.
  4. Intenta ejecutarlo y debería funcionar bien.

Un pequeño ejemplo:

// 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; 
} 

Esta clase cargar un archivo con el nombre pFileName y colocarlo en su variable miembro de mFileContents. (Tenga en cuenta que debe tener una función public get como vector<string> getFileContents() para acceder a la mFileContents porque es private)

EDITAR: El ejemplo anterior funcionará en iOS, sin embargo, no lo hará en los dispositivos Android. Para solucionar esto, en lugar de usar ifstream, use CCFileUtils::sharedUtils() -> getFileData(). Junto con CCFileUtils::sharedUtils() -> fullPathFromRelativePath(), podremos lograr nuestro objetivo de leer un archivo de texto sin formato que funcione tanto en iOS como en Android.

La clase FileReader sería entonces así:

// 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

¿Qué sucede si tiene un gran archivo de datos en Android y no puede permitirse leer todo el archivo con getFileData()? Sería bueno tener más acceso directo ... como 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

Gracias por la ayuda. Aunque lo tengo funcionando usando 'CCFileUtils'. – alxcyl

+0

Intenté usar 'getFileData()' pero recibí un error que decía 'Error de aserción: (¡Nombre de archivo de psz! = __null && pSize! = __null && pszMode! = __null), función getFileData, archivo CCFileUtils.mm, línea 450. ' I lo usé así: 'unsigned char * posdataLoc = CCFileUtils :: sharedFileUtils() -> getFileData (" POSDATA.GAMEDATA "," r ", 0);' – alxcyl

+0

Tengo 'getFileData()' trabajando ahora. Cuando lo'cout' en la consola, muestra caracteres adicionales al azar en el extremo. Extraño. – alxcyl

0

Puede hacer referencia de la Wiki de Cocos Read/write file in cocos2d

+0

No copie y pegue el mismo enlace en varias preguntas. Esto no es una respuesta sino un comentario en el mejor de los casos. – nikhil

Cuestiones relacionadas