Skip to content

Commit f8ed20e

Browse files
PatriceJiangminggo
authored andcommitted
Android: CCFileUtils listFiles impl (cocos2d#19044)
1 parent 7d840ac commit f8ed20e

File tree

5 files changed

+88
-2
lines changed

5 files changed

+88
-2
lines changed

cocos/base/ZipUtils.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <zlib.h>
3636
#include <assert.h>
3737
#include <stdlib.h>
38+
#include <set>
3839

3940
#include "base/CCData.h"
4041
#include "base/ccMacros.h"
@@ -609,6 +610,39 @@ bool ZipFile::fileExists(const std::string &fileName) const
609610
return ret;
610611
}
611612

613+
std::vector<std::string> ZipFile::listFiles(const std::string &pathname) const
614+
{
615+
616+
// filter files which `filename.startsWith(pathname)`
617+
// then make each path unique
618+
619+
std::set<std::string> fileSet;
620+
ZipFilePrivate::FileListContainer::const_iterator it = _data->fileList.begin();
621+
ZipFilePrivate::FileListContainer::const_iterator end = _data->fileList.end();
622+
//ensure pathname ends with `/` as a directory
623+
std::string dirname = pathname[pathname.length() -1] == '/' ? pathname : pathname + "/";
624+
while(it != end)
625+
{
626+
const std::string &filename = it->first;
627+
if(filename.substr(0, dirname.length()) == dirname)
628+
{
629+
std::string suffix = filename.substr(dirname.length());
630+
auto pos = suffix.find("/");
631+
if (pos == std::string::npos)
632+
{
633+
fileSet.insert(suffix);
634+
}
635+
else {
636+
//fileSet.insert(parts[0] + "/");
637+
fileSet.insert(suffix.substr(0, pos + 1));
638+
}
639+
}
640+
it++;
641+
}
642+
643+
return std::vector<std::string>(fileSet.begin(), fileSet.end());
644+
}
645+
612646
unsigned char *ZipFile::getFileData(const std::string &fileName, ssize_t *size)
613647
{
614648
unsigned char * buffer = nullptr;

cocos/base/ZipUtils.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,16 @@ typedef struct unz_file_info_s unz_file_info;
265265
*/
266266
bool fileExists(const std::string &fileName) const;
267267

268+
269+
/**
270+
* Get files and folders in pathname
271+
*
272+
* @param dirname
273+
* @return
274+
*/
275+
std::vector<std::string> listFiles(const std::string &pathname) const;
276+
277+
268278
/**
269279
* Get resource file data from a zip file.
270280
* @param fileName File name

cocos/platform/CCFileUtils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1062,7 +1062,7 @@ std::string FileUtils::getFullPathForDirectoryAndFilename(const std::string& dir
10621062
ret += filename;
10631063

10641064
// if the file doesn't exist, return an empty string
1065-
if (!isFileExistInternal(ret)) {
1065+
if (!isFileExistInternal(ret) && !isDirectoryExistInternal(ret)) {
10661066
ret = "";
10671067
}
10681068
return ret;

cocos/platform/android/CCFileUtils-android.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,48 @@ long FileUtilsAndroid::getFileSize(const std::string& filepath) const
289289
return size;
290290
}
291291

292+
std::vector<std::string> FileUtilsAndroid::listFiles(const std::string& dirPath) const
293+
{
294+
295+
if(isAbsolutePath(dirPath)) return FileUtils::listFiles(dirPath);
296+
297+
std::vector<std::string> fileList;
298+
string fullPath = fullPathForFilename(dirPath);
299+
300+
static const std::string apkprefix("assets/");
301+
string relativePath = "";
302+
size_t position = fullPath.find(apkprefix);
303+
if (0 == position) {
304+
// "assets/" is at the beginning of the path and we don't want it
305+
relativePath += fullPath.substr(apkprefix.size());
306+
} else {
307+
relativePath = fullPath;
308+
}
309+
310+
if(obbfile) return obbfile->listFiles(relativePath);
311+
312+
if (nullptr == assetmanager) {
313+
LOGD("... FileUtilsAndroid::assetmanager is nullptr");
314+
return fileList;
315+
}
316+
317+
auto *dir = AAssetManager_openDir(assetmanager, relativePath.c_str());
318+
if(nullptr == dir) {
319+
LOGD("... FileUtilsAndroid::failed to open dir %s", relativePath.c_str());
320+
AAssetDir_close(dir);
321+
return fileList;
322+
}
323+
const char *tmpDir = nullptr;
324+
while((tmpDir = AAssetDir_getNextFileName(dir))!= nullptr)
325+
{
326+
string filepath(tmpDir);
327+
if(isDirectoryExistInternal(filepath)) filepath += "/";
328+
fileList.push_back(filepath);
329+
}
330+
AAssetDir_close(dir);
331+
return fileList;
332+
}
333+
292334
FileUtils::Status FileUtilsAndroid::getContents(const std::string& filename, ResizableBuffer* buffer) const
293335
{
294336
EngineDataManager::onBeforeReadFile();

cocos/platform/android/CCFileUtils-android.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class CC_DLL FileUtilsAndroid : public FileUtils
7373
virtual bool isAbsolutePath(const std::string& strPath) const override;
7474

7575
virtual long getFileSize(const std::string& filepath) const override;
76-
76+
virtual std::vector<std::string> listFiles(const std::string& dirPath) const override;
7777
private:
7878
virtual bool isFileExistInternal(const std::string& strFilePath) const override;
7979
virtual bool isDirectoryExistInternal(const std::string& dirPath) const override;

0 commit comments

Comments
 (0)