Android: CCFileUtils listFiles impl (#19044)

This commit is contained in:
Arnold 2018-09-19 18:05:16 +08:00 committed by minggo
parent 7d840ac6e1
commit f8ed20e4b3
5 changed files with 88 additions and 2 deletions

View File

@ -35,6 +35,7 @@
#include <zlib.h>
#include <assert.h>
#include <stdlib.h>
#include <set>
#include "base/CCData.h"
#include "base/ccMacros.h"
@ -609,6 +610,39 @@ bool ZipFile::fileExists(const std::string &fileName) const
return ret;
}
std::vector<std::string> ZipFile::listFiles(const std::string &pathname) const
{
// filter files which `filename.startsWith(pathname)`
// then make each path unique
std::set<std::string> 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<std::string>(fileSet.begin(), fileSet.end());
}
unsigned char *ZipFile::getFileData(const std::string &fileName, ssize_t *size)
{
unsigned char * buffer = nullptr;

View File

@ -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<std::string> listFiles(const std::string &pathname) const;
/**
* Get resource file data from a zip file.
* @param fileName File name

View File

@ -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;

View File

@ -289,6 +289,48 @@ long FileUtilsAndroid::getFileSize(const std::string& filepath) const
return size;
}
std::vector<std::string> FileUtilsAndroid::listFiles(const std::string& dirPath) const
{
if(isAbsolutePath(dirPath)) return FileUtils::listFiles(dirPath);
std::vector<std::string> 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();

View File

@ -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<std::string> 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;