对于想了解cocos2dxCCFileUtils::sharedFileUtils()静态调用的读者,本文将提供新的信息,我们将详细介绍调用静态类,并且为您提供关于android.os.FileUti
对于想了解cocos2dx CCFileUtils::sharedFileUtils() 静态调用的读者,本文将提供新的信息,我们将详细介绍调用静态类,并且为您提供关于android.os.FileUtils的实例源码、cocos creator基础-(二十五)FileUtils本地文件读写、Cocos2d-x FileUtils学习笔记、cocos2d-x3.2源码分析(一)类FileUtils--实现把资源放在Resources文件目录下达到多平台的引用的有价值信息。
本文目录一览:- cocos2dx CCFileUtils::sharedFileUtils() 静态调用(调用静态类)
- android.os.FileUtils的实例源码
- cocos creator基础-(二十五)FileUtils本地文件读写
- Cocos2d-x FileUtils学习笔记
- cocos2d-x3.2源码分析(一)类FileUtils--实现把资源放在Resources文件目录下达到多平台的引用
cocos2dx CCFileUtils::sharedFileUtils() 静态调用(调用静态类)
如题
CCFileUtils::sharedFileUtils()
静态调用,也就是在cpp文件的函数外面调用
Android平台会无故崩溃,跟踪调试发现在CCFileUtilsAndroid.cpp的42行过不去即
CCFileUtils* CCFileUtils::sharedFileUtils() { if (s_sharedFileUtils == NULL) { s_sharedFileUtils = new CCFileUtilsAndroid(); s_sharedFileUtils->init(); std::string resourcePath = getApkPath(); s_pZipFile = new ZipFile(resourcePath,"assets/"); } return s_sharedFileUtils; }
std::string resourcePath = getApkPath();
这行 然后查看getApkPath()函数,里面也就返回string g_apkPath的c_str()
最后没查出别的有用信息,不过此时g_apkPath应该是null,因为g_apkPath是依靠java那边回调才设置的值
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetApkPath(jnienv* env,jobject thiz,jstring apkPath) { g_apkPath = JniHelper::jstring2string(apkPath); }
而静态调用了CCFileUtils::sharedFileUtils(),发生在静态区
而java加载libgame.so的方法如下
static { System.loadLibrary("game"); }可想而知getApkPath的调用就会在nativeSetApkPath之前
所以sharedFileUtils()就不要在全局区调用了(也就是静态调用)
但是ios平台,是没有问题
ps:遇到问题就先记录,以免以后再次遇到,耗费时间去找问题
android.os.FileUtils的实例源码
public SharedPreferencesImpl(File file,int mode,Map initialContents,Handler mainHandler) { mFile = file; this.mainHandler = mainHandler; mBackupFile = makeBackupFile(file); mMode = mode; mloaded = initialContents != null; mMap = initialContents != null ? initialContents : new HashMap<String,Object>(); FileUtils.FileStatus stat = new FileUtils.FileStatus(); if(FileUtils.getFileStatus(file.getPath(),stat)) { mStatTimestamp = stat.mtime; } mListeners = new WeakHashMap<OnSharedPreferencechangelistener,Object>(); }
public boolean hasFileChangedUnexpectedly() { synchronized (this) { if (mdiskWritesInFlight > 0) { // If we kNow we caused it,it's not unexpected. if (DEBUG) Log.d(TAG,"disk write in flight,not unexpected."); return false; } } FileUtils.FileStatus stat = new FileUtils.FileStatus(); if (!FileUtils.getFileStatus(mFile.getPath(),stat)) { return true; } synchronized (this) { return mStatTimestamp != stat.mtime || mStatSize != stat.size; } }
private static FileOutputStream createFileOutputStream(File file) { FileOutputStream str = null; try { str = new FileOutputStream(file); } catch (FileNotFoundException e) { File parent = file.getParentFile(); if (!parent.mkdir()) { Log.e(TAG,"Couldn't create directory for SharedPreferences file " + file); return null; } FileUtils.setPermissions( parent.getPath(),FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,-1,-1); try { str = new FileOutputStream(file); } catch (FileNotFoundException e2) { Log.e(TAG,"Couldn't create SharedPreferences file " + file,e2); } } return str; }
private static void setFilePermissionsFromMode(String name,int extraPermissions) { int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR |FileUtils.S_IRGRP|FileUtils.S_IWGRP |extraPermissions; if ((mode& Context.MODE_WORLD_READABLE) != 0) { perms |= FileUtils.S_IROTH; } if ((mode& Context.MODE_WORLD_WRITEABLE) != 0) { perms |= FileUtils.S_IWOTH; } if (DEBUG) { Log.i(TAG,"File " + name + ": mode=0x" + Integer.toHexString(mode) + ",perms=0x" + Integer.toHexString(perms)); } FileUtils.setPermissions(name,perms,- 1,- 1); }
public void replace(Map newContents,FileUtils.FileStatus stat) { synchronized (this) { mloaded = true; if (newContents != null) { mMap = newContents; } if (stat != null) { mStatTimestamp = stat.mtime; mStatSize = stat.size; } } }
/** * Start a new write operation on the file. This returns a FileOutputStream * to which you can write the new file data. The existing file is replaced * with the new data. You <em>must not</em> directly close the given * FileOutputStream; instead call either {@link #finishWrite(FileOutputStream)} * or {@link #failWrite(FileOutputStream)}. * * <p>Note that if another thread is currently performing * a write,this will simply replace whatever that thread is writing * with the new file being written by this thread,and when the other * thread finishes the write the new write operation will no longer be * safe (or will be lost). You must do your own threading protection for * access to AtomicFile. */ public FileOutputStream startWrite() throws IOException { // Rename the current file so it may be used as a backup during the next read if (mBaseName.exists()) { if (!mBackupName.exists()) { if (!mBaseName.renameto(mBackupName)) { Log.w("AtomicFile","Couldn't rename file " + mBaseName + " to backup file " + mBackupName); } } else { mBaseName.delete(); } } FileOutputStream str = null; try { str = new FileOutputStream(mBaseName); } catch (FileNotFoundException e) { File parent = mBaseName.getParentFile(); if (!parent.mkdir()) { throw new IOException("Couldn't create directory " + mBaseName); } FileUtils.setPermissions( parent.getPath(),-1); try { str = new FileOutputStream(mBaseName); } catch (FileNotFoundException e2) { throw new IOException("Couldn't create " + mBaseName); } } return str; }
/** * Call when you have successfully finished writing to the stream * returned by {@link #startWrite()}. This will close,sync,and * commit the new data. The next attempt to read the atomic file * will return the new file stream. */ public void finishWrite(FileOutputStream str) { if (str != null) { FileUtils.sync(str); try { str.close(); mBackupName.delete(); } catch (IOException e) { Log.w("AtomicFile","finishWrite: Got exception:",e); } } }
/** * Call when you have Failed for some reason at writing to the stream * returned by {@link #startWrite()}. This will close the current * write stream,and roll back to the prevIoUs state of the file. */ public void failWrite(FileOutputStream str) { if (str != null) { FileUtils.sync(str); try { str.close(); mBaseName.delete(); mBackupName.renameto(mBaseName); } catch (IOException e) { Log.w("AtomicFile","failWrite: Got exception:",e); } } }
/** * Called after a successful completion to take any necessary action on the transfered file. */ private void finalizeDestinationFile(State state) { if (state.mFilename != null) { // make sure the file is readable FileUtils.setPermissions(state.mFilename,0644,-1); } }
/** * Called after a successful completion to take any necessary action on the * downloaded file. */ private void finalizeDestinationFile(State state) throws StopRequest { // make sure the file is readable FileUtils.setPermissions(state.mFilename,-1); syncDestination(state); }
cocos creator基础-(二十五)FileUtils本地文件读写
cc.Class({
extends: cc.Component,
properties: {
// foo: {
// default: null, // The default value will be used only when the component attaching
// to a node for the first time
// url: cc.Texture2D, // optional, default is typeof default
// serializable: true, // optional, default is true
// visible: true, // optional, default is true
// displayName: ''Foo'', // optional
// readonly: false, // optional, default is false
// },
// ...
},
// use this for initialization
onLoad: function () {
// jsb.fileUtils获取全局的工具类的实例, cc.director;
// 如果是在电脑的模拟器上,就会是安装路径下模拟器的位置;
// 如果是手机上,那么就是手机OS为这个APP分配的可以读写的路径;
// jsb --> javascript binding --> jsb是不支持h5的
var writeable_path = jsb.fileUtils.getWritablePath();
console.log(writeable_path);
// 要在可写的路径先创建一个文件夹
var new_dir = writeable_path + "new_dir";
// 路径也可以是 外部存储的路径,只要你有可写外部存储的权限;
// getWritablePath这个路径下,会随着我们的程序卸载而删除,外部存储除非你自己删除,否者的话,卸载APP数据还在;
if(!jsb.fileUtils.isDirectoryExist(new_dir)) {
jsb.fileUtils.createDirectory(new_dir);
}
else {
console.log("dir is exist!!!");
}
// 读写文件我们分两种,文本文件, 二进制文件;
// (1)文本文件的读,返回的是一个string对象
var str_data = jsb.fileUtils.getStringFromFile(new_dir + "/test_str_read.txt");
console.log(str_data);
str_data = "hello test_write !!!!!"
jsb.fileUtils.writeStringToFile(str_data, new_dir + "/test_str_write.txt");
// (2)二进制文件的读写, Uint8Array --> js对象
var bin_array = jsb.fileUtils.getDataFromFile(new_dir + "/test_bin_read.png");
console.log(bin_array[0], bin_array[1]); // 使用这个就能访问二进制的每一个字节数据;
jsb.fileUtils.writeDataToFile(bin_array, new_dir + "/test_bin_write.png");
// end
// 删除文件和文件夹
// jsb.fileUtils.removeFile(new_dir + "/test_bin_write.png");
// jsb.fileUtils.removeDirectory(new_dir);
},
// called every frame, uncomment this function to activate update callback
// update: function (dt) {
// },
});
Cocos2d-x FileUtils学习笔记
文件的写入:
直接通过FileUtils来保存键值对,示例如下:
Value a=Value(10);
Value b=Value("Hello");
ValueMap valueMap;
valueMap.insert(std::make_pair("number",a));
valueMap.insert(std::make_pair("name",b));
std::string filepath=FileUtils::getInstance()->getWritablePath();//获取可写路径,只能在可写路径下进行文件的写入
log("path is %s",filepath.c_str());//打印可写路径
FileUtils::getInstance()->writetoFile(valueMap,filepath+"/hh.plist");
//用模拟器console下查看产生的hh.plist文件的路径和文件内容如下:
localhost:Documents wangwei$ pwd
/Users/wangwei/Library/Developer/CoreSimulator/Devices/84781560-37A5-4F81-B2E6-39DD8C8757B6/data/Containers/Data/Application/4EB4CD53-4574-4ED6-A82F-FBA88C920ABF/Documents
localhost:Documents wangwei$ ls
hh.plist
localhost:Documents wangwei$ more hh.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>name</key>
<string>Hello</string>
<key>number</key>
<integer>10</integer>
</dict>
</plist>
用真机调试的文件路径如下:
path is /var/mobile/Containers/Data/Application/2F159D86-297F-4ECA-A8A0-CD35287078AF/Documents/
文件的读取:
ValueMap read_valueMap;
read_valueMap=FileUtils::getInstance()->getValueMapFromFile(filepath+"/hh.plist");
std::string name=valueMap.at("name").asstring();
log("read name is %s",name.c_str());
cocos2d-x3.2源码分析(一)类FileUtils--实现把资源放在Resources文件目录下达到多平台的引用
当你创建TMXTiledMaP* tilemap=TMXTiledMap::create("test1.tmx")或Sprite *sprite=Sprite("HelloWorld.p-ng"),有没有产生这样的疑问--为什么把资源test1.tmx和HelloWorld.png放在项目目录下的Resources文件中即可直接引用而不用标明具体路径,并且可以在多个平台下引用?或许很多人就会这样说:“别人告诉我放在这个文件夹中就可以了,我自己使用确实可行,也没有出错,我就没有多去探究了”。如果你想知道这具体原因,就要阅读下面的分析了。如果你并不关心其原因,你可以关闭这个网页了。
我以TMXTiledMap::Create函数为讲解对象。
代码1:
- <spanstyle="font-size:18px;">TMXTiledMaP*TMXTiledMap::create(conststd::string&tmxFile)
- {
- TMXTiledMaP*ret=newTMXTiledMap();
- if(ret->initWithTMXFile(tmxFile))
- {
- ret->autorelease();
- returnret;
- }
- CC_SAFE_DELETE(ret);
- returnnullptr;
- }</span>
代码2:
- <spanstyle="font-size:18px;">boolTMXTiledMap::initWithTMXFile( CCASSERT(tmxFile.size()>0,"FastTMXTiledMap:tmxfileshouldnotbeempty");
- setContentSize(Size::ZERO);
- TMXMapInfo*mapInfo=TMXMapInfo::create(tmxFile);
- if(!mapInfo)
- returnfalse;
- }
- CCASSERT(!mapInfo->getTilesets().empty(),"FastTMXTiledMap:Mapnotfound.Pleasecheckthefilename.");
- buildWithMapInfo(mapInfo);
- true;
- }</span>
今天关于cocos2dx CCFileUtils::sharedFileUtils() 静态调用和调用静态类的讲解已经结束,谢谢您的阅读,如果想了解更多关于android.os.FileUtils的实例源码、cocos creator基础-(二十五)FileUtils本地文件读写、Cocos2d-x FileUtils学习笔记、cocos2d-x3.2源码分析(一)类FileUtils--实现把资源放在Resources文件目录下达到多平台的引用的相关知识,请在本站搜索。
本文标签: