有demo么,上传一个呗
//初始化filemap
static std::map <std::string, Data> _fileMap;
//重置filemap
static void resetFileMap() {
std::map<std::string, Data>::iterator iter;
for(iter =_fileMap.begin();iter!=_fileMap.end();iter++)
{
//清理cocos的data
(iter->second).clear();
_fileMap.erase(iter);
}
std::map<std::string, Data> empty_map1;
_fileMap.swap(empty_map1);
_fileMap.clear();
}
//设置filemap key值
static void setFileMap(std::string key,Data data){
// Data retData;
// //retData.fastSet(l_it->second.getBytes(),l_it->second.getSize());
// retData.copy(data.getBytes(),data.getSize());
Data clone;
_fileMap[key] = data;
}
//获取filemap 根据key值
static Data getFileMap(std::string key){
// std::map<std::string, Data>::iterator iter;
// iter=_fileMap.find(key);
// if(iter==_fileMap.end())
// {
// CCLOG("Get data from cache file null");
// return Data::Null;
// }
// for(auto item =_fileMap.begin();item!=_fileMap.end();item++)
// {
// if(item->first==key)
// {
// auto value= item->second;
// CCLOG("Get data from cache file %s", key.c_str());
// return value;
// //do someting.....
// }
// }
std::map<std::string, Data >::iterator l_it;
l_it=_fileMap.find(key);
int count=0;
for(auto it=_fileMap.begin();it!=_fileMap.end();it++) {
count++;
}
CCLOG("size:%s \n",std::to_string(count).c_str());
if(l_it==_fileMap.end()){
CCLOG("Get data from cache null");
return Data::Null;
}
else{
CCLOG("Get data from cache key333:%s \n",l_it->first.c_str());
CCLOG("Get data from cache key:%s \n",key.c_str());
//CCLOG("Get data from cache key:%s \n content:%s",key.c_str(),l_it->second.getBytes() );
Data retData;
//// //retData.fastSet(l_it->second.getBytes(),l_it->second.getSize());
retData.copy(l_it->second.getBytes(),l_it->second.getSize());
return retData;
//return l_it->second;
}
// CCLOG("Get data from cache null");
// return Data::Null;
}
//设置filemap key值
static void setFileMapIsNull(std::string key){
Data assignData = getFileMap(key);
if(!assignData.isNull()){
assignData.clear();
}
}
static Data getData(const std::string& filename, bool forString)
{
if (filename.empty())
{
return Data::Null;
}
const char* mode = nullptr;
if (forString)
{
mode = "rt";
}
else{
mode = "rb";
}
std::string fileName2=filename.c_str();
replace(fileName2.begin(),fileName2.end(),'/','_');
replace(fileName2.begin(),fileName2.end(),'.','_');
fileName2=fileName2+"_"+mode;
Data tmp = getFileMap(fileName2);
if(!tmp.isNull()){
// CCLOG("first getCahceData %s", filename.c_str());
return tmp;
}
Data ret;
unsigned char* buffer = nullptr;
size_t size = 0;
size_t readsize;
//std::string bufferC = NULL;
auto fileutils = FileUtils::getInstance();
do
{
// Read the file from hardware
std::string fullPath = fileutils->fullPathForFilename(filename);
FILE *fp = fopen(fileutils->getSuitableFOpen(fullPath).c_str(), mode);
CC_BREAK_IF(!fp);
fseek(fp,0,SEEK_END);
size = ftell(fp);
fseek(fp,0,SEEK_SET);
if (forString&&false)
{
buffer = (unsigned char*)malloc(sizeof(unsigned char) * (size + 1));
buffer[size] = '\0';
}
else
{
buffer = (unsigned char*)malloc(sizeof(unsigned char) * size);
}
readsize = fread(buffer, sizeof(unsigned char), size, fp);
fclose(fp);
if (forString && readsize < size)
{
CCLOG("为什么进到这里");
buffer[readsize] = '\0';
}
// bufferC= ((const char*)buffer);
} while (0);
if (nullptr == buffer || 0 == readsize)
{
CCLOG("Get data from file %s failed", filename.c_str());
}
else
{
ret.fastSet(buffer, readsize);
CCLOG("第一次设置数据%s:", fileName2.c_str());
// unsigned char* readSizeOut=( (unsigned char *) &readsize);
// CCLOG("readsize%s:", readSizeOut);
// unsigned char* sizeOut=( (unsigned char *) &size);
// CCLOG("size%s:", sizeOut);
// Data retData;
// retData.copy(buffer,readsize);
setFileMap(fileName2.c_str(), ret);
}
return getFileMap(fileName2);
}
std::string FileUtils::getStringFromFile(const std::string& filename)
{
Data data = getData(filename, true);
if (data.isNull())
return "";
std::string ret((const char*)data.getBytes());
return ret;
}
表现为这个按照key读取的data getBytes 会在之前的数据基础上加一些莫名其妙的data,导致读取后解析失败,
比如:
正确为{“KEY1”:“123456”}
有时就会变成{“KEY1”:“123456”}+ 或者{“KEY1”:“123456”}[ 3 这种后面会加一些乱起八早的东西,但有时是对的,能读到正确值
哪个大佬能看下 c++ 不是很懂
我的demo的意思是你上传一下我能调试的工程
然后你的文件缓存准备做在引擎的FileUtils中?
工程太大了,基本就改了这个文件,然后 get出来的数据有时莫名其妙多出一些奇怪字符
ddddddddddddd33333bbbbb
反正我是不建议做在FileUtils中的因为图片也从这走,然后图片还有TextureCache和SpriteFrameCache到时候你的内存可能会不够用,都是缓存
可以做判断 只缓存.json结尾的
额,只要你喜欢就好
再定个水自费
std::string ret((const char*)data.getBytes()); 这句改为
std::string ret((const char*)data.getBytes(), data.getSize());
为什么的话,string如果你直接只传数据的头指针将一直读到结束符为止组装string
帮人还得自己写demo
调试
感谢大佬真的是这个原因,感谢 
还有个疑问 ,我注掉了缓存,我在这里static Data getData(const std::string& filename, bool forString) 方法前后打了时间戳,除了第一次加载,发现之后并没有时间消耗
迷惑了,io不是应该有消耗的吗,我读取的是一个260kb的json文件
打印如下:
4:16 PM 在c++中读取 getData1 asdd.json, 1592208968618
4:16 PM 在c++中读取 getData2 asdd.json, 1592208968618
为什么只第一次是有延迟,之后的读取 一个200多kb的文件读取不应该多少有点耗时吗?如果没有耗时,file的缓存好像没什么意义?
你怎么输出时间戳我不知道没法说,但是你之间macllo的内存要注意啥时候free,不然就是内存泄漏
io 是从硬盘读到内存,理论上这个getData每次应该会有时间消耗,但好像读了一次 下次没有任何时间消耗,时间戳打印到了毫秒,前后没消耗,怪异
没找到缓存代码,是不是读到硬盘缓存去了,给自动缓存了?~
这个你自己研究研究吧,搞懂了也能知道点底层的知识
再次感谢大佬帮忙~