西西軟件園多重安全檢測下載網站、值得信賴的軟件下載站!
軟件
軟件
文章
搜索

首頁編程開發(fā)其它知識 → cocos2d-x判斷文件是否存在for android

cocos2d-x判斷文件是否存在for android

相關軟件相關文章發(fā)表評論 來源:西西整理時間:2013/6/4 8:32:03字體大小:A-A+

作者:葉尚海點擊:202次評論:0次標簽: cocos2d-x

Cocos2D-X完整包v2.2.1 官方最新版
  • 類型:編程工具大。338.7M語言:中文 評分:3.3
  • 標簽:
立即下載

最近在做一款cocos2d-x的游戲,想用access去判斷文件是否存在,在windows和ios平臺完全ok,但是android怎么都不可以。后來發(fā)現,原來anroid的資源文件都還在apk中未解壓出來,cocos2d-x針對android時這樣讀取文件的:

 1 unsigned char* CCFileUtils::getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize)
 2 {    
 3     unsigned char * pData = 0;
 4     string fullPath(pszFileName);
 5 
 6     if ((! pszFileName) || (! pszMode))
 7     {
 8         return 0;
 9     }
10 
11     if (!m_obPreloadDirectory.empty()) {
12         do {
13             std::string filename = pszFileName;
14             size_t pos = filename.rfind("/");
15             if (pos != std::string::npos)
16                 filename = filename.substr(pos + 1);
17             filename = m_obPreloadDirectory + filename;
18             FILE *fp = fopen(filename.c_str(), pszMode);
19             CC_BREAK_IF(!fp);
20 
21             unsigned long size;
22             fseek(fp,0,SEEK_END);
23             size = ftell(fp);
24             fseek(fp,0,SEEK_SET);
25             pData = new unsigned char[size];
26             size = fread(pData,sizeof(unsigned char), size,fp);
27             fclose(fp);
28 
29             if (pSize)
30             {
31                 *pSize = size;
32             }
33 
34             if (pData != NULL)
35                 return pData;
36         } while (0);
37     }
38 
39     if (pszFileName[0] != '/')
40     {
41         // read from apk
42         string pathWithoutDirectory = fullPath;
43         
44         fullPath.insert(0, m_obDirectory.c_str());
45         fullPath.insert(0, "assets/");
46         pData =  CCFileUtils::getFileDataFromZip(s_strResourcePath.c_str(), fullPath.c_str(), pSize);
47         
48         if (! pData && m_obDirectory.size() > 0)
49         {
50             // search from root
51             pathWithoutDirectory.insert(0, "assets/");
52             pData =  CCFileUtils::getFileDataFromZip(s_strResourcePath.c_str(), pathWithoutDirectory.c_str(), pSize);
53         }
54     }
55     else
56     {
57         do 
58         {
59             // read rrom other path than user set it
60             FILE *fp = fopen(pszFileName, pszMode);
61             CC_BREAK_IF(!fp);
62 
63             unsigned long size;
64             fseek(fp,0,SEEK_END);
65             size = ftell(fp);
66             fseek(fp,0,SEEK_SET);
67             pData = new unsigned char[size];
68             size = fread(pData,sizeof(unsigned char), size,fp);
69             fclose(fp);
70 
71             if (pSize)
72             {
73                 *pSize = size;
74             }            
75         } while (0);        
76     }
77 
78     /*if (! pData && isPopupNotify())
79     {
80         std::string title = "Notification";
81         std::string msg = "Get data from file(";
82         msg.append(fullPath.c_str()).append(") failed!");
83         CCMessageBox(msg.c_str(), title.c_str());
84     }*/
85 
86     return pData;
87 }

這個方法在cocos2d-x源碼platform/android的CCFileUtils類中,我們可以看到pData =  CCFileUtils::getFileDataFromZip(s_strResourcePath.c_str(), pathWithoutDirectory.c_str(), pSize)這樣一段代碼,其實它是直接去獲取apk包里面的資源,所以你access就行不通了。

有兩種方式可以解決這個問題:

1、直接判斷CCFileUtils::getFileData返回值是否為NULL,不過這個方式有一個問題,當你同一個頁面判斷的資源很多的話,這個是很耗時的,因為它每次判斷都要去解壓打包,這種方式只適合判斷少量文件,最好是單個文件是否存在。

2、將apk中的資源文件單獨拷貝出來放到一個單獨的文件夾下,比如/data/data/apkPackage/,當然拷貝也是很耗時的,通常這一步放到程序啟動的時候處理,如同加載資源一樣,這樣做以后,可以直接判斷這個文件夾里面是不是存在這個文件,對于同一個頁面判斷多個資源,是相當快的。

接下來講一下第二種方式的具體作法:

在CCFileUtils類中添加兩個方法:

 1 bool CCFileUtils::isFileExist(const char* pFileName)
 2 {
 3     if( !pFileName ) return false;
 4     //strFilePathName is :/data/data/ + package name
 5     std::string filePath = m_obPreloadDirectory + pFileName;
 6  
 7     FILE *fp = fopen(filePath.c_str(),"r");
 8     if(fp)
 9     {
10         fclose(fp);
11         return true;
12     }
13     return false;
14 }
15 
16 void CCFileUtils::copyData(const char* pFileName)
17 {
18     std::string strPath = fullPathFromRelativePath(pFileName);
19     unsigned long len = 0;
20     unsigned char *data = NULL;
21  
22     data = getFileData(strPath.c_str(),"r",&len);
23     if(data==NULL)
24         return;
25     std::string destPath = m_obPreloadDirectory;
26     destPath += pFileName;
27     FILE *fp = fopen(destPath.c_str(),"w+");
28     fwrite(data,sizeof(char),len,fp);
29     fclose(fp);
30     delete []data;
31     data = NULL;
32 }

isFileExist可以用來判斷文件是否存在,copyData就是將apk中的資源文件拷貝到另外一個目錄,當然你可以選取你需要的資源進行拷貝,因為拷貝也是一項耗時的操作。這兩個方法里面都有一個私有成員m_obPreloadDirectory,這其實就是你想把文件拷貝到哪里的目錄,很簡單,給它一個set方法,外界設置一下這個目錄就可以了,一般情況都設為/data/data/packagename。

在拷貝資源前先通過isFileExist判斷一下文件是否存在,存在就不需要再拷貝了,因為剛才說過拷貝很耗時。

接下來就可以通過isFileExist方法來判斷文件是否存在了。(在不斷的嘗試中總結經驗,以幫助后面的人更快的上路)

    相關評論

    閱讀本文后您有什么感想? 已有人給出評價!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過難過
    • 5 囧
    • 3 圍觀圍觀
    • 2 無聊無聊

    熱門評論

    最新評論

    發(fā)表評論 查看所有評論(0)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字數: 0/500 (您的評論需要經過審核才能顯示)