Set relative path using Working Directory

I want to set the path where save files are written to

FileUtils::getInstance()->setWritablePath()

My issue is that I want to set it relative to the working directory (or top level of the project directory). Ideally, the /Resources folder looks like a great spot. However, I don’t know how to query that location. When I call getWritablePath(), my path returned is the Documents folder of my Username, however I want to avoid absolute paths so it’s portable, and don’t want that location to be the writable path anyway. Any tips?

Lastly, the way my game is written, I want to save text files, or my own binary with great flexibility, so built in context saves won’t help

This is where files should be saved… Most OS’s don’t support saving out side of this, IIRC.

For multi-platform, you need to use “getWritablePath()”.
Especially, Android can not write to files in Resources/.
This is a specification, it can not be avoided.
This is a very famous and well-known spec.

1 Like

IIRC? What is that?

Are there common target locations developers like to save their data? It would be great to have them not in some flat dumping ground like the Documents folder. I suppose having a sub folder in Documents for saved files would be workable, just not ideal.

@JimJam You can save to a sub-directory inside of getWritablePath() if you want, but that is your root.

IIRC - if I recall correctly.

1 Like

Well-known spec from Android’s context, cocos2d, or the interaction of both? I’ve been reading the API, but haven’t found it terribly descriptive, and many of the cocos2d tutorials are deprecated (v2.0 or earlier). I’m still getting by and it is definitely getting easier as I get a handle on fundamentals, I have heard that cocos2d has a higher learning curve.

thanks for your help, slack. That’s what I’ll use. My last question for you was, if you know, what IIRC stands for.

We definitely require you are comfortable coding. Have you reviewed our Programmers Guide?

1 Like

I said above - IIRC == If I recall correctly. :slight_smile:

Yes I have, although I stopped after an earlier article that suggests running the example projects. After a few hours of searching, it turns out there was a bug for the 2nd example, particularly on mac os. I’ll likely return to it though, It’s good to know that’s a good starting resource despite that first hiccup.

I am an experienced coder, I have a degree in computer science and engineering actually. I’ve worked plenty with C but am still pretty little experienced with C++.

Oh, haha thank you

It is well known as the context of Android.
Android applications are archived as a single apk file.
The Resources directory of the cocos2d-x project is stored in this archive.
In other words, in the Android application, the Resources directory is Read Only.

By the way, on Android files in the Resources directory are copied to the assets directory.
This can be accessed by the AssetManager class of the Android SDK (java), but there is no function to write.

Everyone wants to write to the assets directory (Resources directory in cocos2d-x), but it always fails.
And They will arrive at this fact.

1 Like

That’s very helpful, thank you! I’ll just use getWriteablePath and virtual file structures by string name then, thank you

If you can tell me more about this, I can review and fix.

So I thought I could simply add a virtual path, if I opened for instance “sub/exmaple.text”, I expected it would create a folder “sub” in the WritablePath’s directory, and add a file “example.txt” to that (wishful thinking, I should have known).

Is there an elegant tool in cocos for creating folders? I would imagine not, I’m thinking my next option is to, depending on OS, handwrite the mkdir command for any file path organization I want. Does this seem correct to you?

We have an API for this :slight_smile:

Hint, it is this: http://www.cocos2d-x.org/docs/api-ref/cplusplus/v3x/dc/d69/classcocos2d_1_1_file_utils.html

and the entire API-ref: http://www.cocos2d-x.org/docs/api-ref/

Perhaps this is what you want to do.

auto fileUtils = FileUtils::getInstance();
std::string subDir = fileUtils->getWritablePath() + "sub/";

if(!fileUtils->isDirectoryExist(subDir)) {
    fileUtils->createDirectory(subDir);
}

std::string text = "this is sample";
std::string filename = "example.txt";

fileUtils->writeStringToFile(text, subDir + filename);

FileUtils provides only a simple API.
For example, directories which are not empty can not be deleted with removeDirectory().
You have to create your own process of recursively deleting the directory.
Basically, think about nothing useful.
There is no other choice but to combine existing basic instructions and make it yourself.

2 Likes

hi, there thanks, I am trying to do the same thing but, every time I call

it adds data to the file but it removing old one

I do not know what you want to do well
Is this something like that?

auto fileUtils = FileUtils::getInstance();

std::string filename = "sample.txt";
std::string path = fileUtils->getWritablePath() + filename;

// current saved data
std::string text = fileUtils->getStringFromFile(path);
// new data
std::string newText = text + "add contents...";
// overwrite
fileUtils->writeStringToFile(newText, path);
3 Likes

thanks for replay, so suppose we want to do log in one file, doesn’t it get more costly every time we add new data? Btw one more question maybe you can help, we have one node and we are using

    this->removeAllChildrenWithCleanup(true);

and now again when we are checking that does it empty or not it still getting nonEmpty and now when i trying to call some method on it, it says object should be non nill