diff --git a/cocos/base/ZipUtils.cpp b/cocos/base/ZipUtils.cpp index 769ceafe8e..8f9fa583cc 100644 --- a/cocos/base/ZipUtils.cpp +++ b/cocos/base/ZipUtils.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include "base/CCData.h" #include "base/ccMacros.h" @@ -609,6 +610,39 @@ bool ZipFile::fileExists(const std::string &fileName) const return ret; } +std::vector ZipFile::listFiles(const std::string &pathname) const +{ + + // filter files which `filename.startsWith(pathname)` + // then make each path unique + + std::set fileSet; + ZipFilePrivate::FileListContainer::const_iterator it = _data->fileList.begin(); + ZipFilePrivate::FileListContainer::const_iterator end = _data->fileList.end(); + //ensure pathname ends with `/` as a directory + std::string dirname = pathname[pathname.length() -1] == '/' ? pathname : pathname + "/"; + while(it != end) + { + const std::string &filename = it->first; + if(filename.substr(0, dirname.length()) == dirname) + { + std::string suffix = filename.substr(dirname.length()); + auto pos = suffix.find("/"); + if (pos == std::string::npos) + { + fileSet.insert(suffix); + } + else { + //fileSet.insert(parts[0] + "/"); + fileSet.insert(suffix.substr(0, pos + 1)); + } + } + it++; + } + + return std::vector(fileSet.begin(), fileSet.end()); +} + unsigned char *ZipFile::getFileData(const std::string &fileName, ssize_t *size) { unsigned char * buffer = nullptr; diff --git a/cocos/base/ZipUtils.h b/cocos/base/ZipUtils.h index 3b7d49708f..6980d248ab 100644 --- a/cocos/base/ZipUtils.h +++ b/cocos/base/ZipUtils.h @@ -265,6 +265,16 @@ typedef struct unz_file_info_s unz_file_info; */ bool fileExists(const std::string &fileName) const; + + /** + * Get files and folders in pathname + * + * @param dirname + * @return + */ + std::vector listFiles(const std::string &pathname) const; + + /** * Get resource file data from a zip file. * @param fileName File name diff --git a/cocos/platform/CCFileUtils.cpp b/cocos/platform/CCFileUtils.cpp index 0e11fb6ed1..50e604f626 100644 --- a/cocos/platform/CCFileUtils.cpp +++ b/cocos/platform/CCFileUtils.cpp @@ -1062,7 +1062,7 @@ std::string FileUtils::getFullPathForDirectoryAndFilename(const std::string& dir ret += filename; // if the file doesn't exist, return an empty string - if (!isFileExistInternal(ret)) { + if (!isFileExistInternal(ret) && !isDirectoryExistInternal(ret)) { ret = ""; } return ret; diff --git a/cocos/platform/android/CCFileUtils-android.cpp b/cocos/platform/android/CCFileUtils-android.cpp index e1bf4ba65b..cf27566406 100644 --- a/cocos/platform/android/CCFileUtils-android.cpp +++ b/cocos/platform/android/CCFileUtils-android.cpp @@ -289,6 +289,48 @@ long FileUtilsAndroid::getFileSize(const std::string& filepath) const return size; } +std::vector FileUtilsAndroid::listFiles(const std::string& dirPath) const +{ + + if(isAbsolutePath(dirPath)) return FileUtils::listFiles(dirPath); + + std::vector fileList; + string fullPath = fullPathForFilename(dirPath); + + static const std::string apkprefix("assets/"); + string relativePath = ""; + size_t position = fullPath.find(apkprefix); + if (0 == position) { + // "assets/" is at the beginning of the path and we don't want it + relativePath += fullPath.substr(apkprefix.size()); + } else { + relativePath = fullPath; + } + + if(obbfile) return obbfile->listFiles(relativePath); + + if (nullptr == assetmanager) { + LOGD("... FileUtilsAndroid::assetmanager is nullptr"); + return fileList; + } + + auto *dir = AAssetManager_openDir(assetmanager, relativePath.c_str()); + if(nullptr == dir) { + LOGD("... FileUtilsAndroid::failed to open dir %s", relativePath.c_str()); + AAssetDir_close(dir); + return fileList; + } + const char *tmpDir = nullptr; + while((tmpDir = AAssetDir_getNextFileName(dir))!= nullptr) + { + string filepath(tmpDir); + if(isDirectoryExistInternal(filepath)) filepath += "/"; + fileList.push_back(filepath); + } + AAssetDir_close(dir); + return fileList; +} + FileUtils::Status FileUtilsAndroid::getContents(const std::string& filename, ResizableBuffer* buffer) const { EngineDataManager::onBeforeReadFile(); diff --git a/cocos/platform/android/CCFileUtils-android.h b/cocos/platform/android/CCFileUtils-android.h index 28bf945a5c..a201075487 100644 --- a/cocos/platform/android/CCFileUtils-android.h +++ b/cocos/platform/android/CCFileUtils-android.h @@ -73,7 +73,7 @@ public: virtual bool isAbsolutePath(const std::string& strPath) const override; virtual long getFileSize(const std::string& filepath) const override; - + virtual std::vector listFiles(const std::string& dirPath) const override; private: virtual bool isFileExistInternal(const std::string& strFilePath) const override; virtual bool isDirectoryExistInternal(const std::string& dirPath) const override;