Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 62 additions & 8 deletions cocos/platform/CCFileUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ std::string FileUtils::getPathForFilename(const std::string& filename, const std
path += file_path;
path += resolutionDirectory;

path = getFullPathForDirectoryAndFilename(path, file);
path = getFullPathForFilenameWithinDirectory(path, file);

return path;
}
Expand Down Expand Up @@ -864,6 +864,60 @@ std::string FileUtils::fullPathForFilename(const std::string &filename) const
return "";
}


std::string FileUtils::fullPathForDirectory(const std::string &dir) const
{
DECLARE_GUARD;

if (dir.empty())
{
return "";
}

if (isAbsolutePath(dir))
{
return dir;
}

// Already Cached ?
auto cacheIter = _fullPathCacheDir.find(dir);
if(cacheIter != _fullPathCacheDir.end())
{
return cacheIter->second;
}
std::string longdir = dir;
std::string fullpath;

if(longdir[longdir.length() - 1] != '/')
{
longdir +="/";
}

for (const auto& searchIt : _searchPathArray)
{
for (const auto& resolutionIt : _searchResolutionsOrderArray)
{
fullpath = searchIt + longdir + resolutionIt;
auto exists = isDirectoryExistInternal(fullpath);

if (exists && !fullpath.empty())
{
// Using the filename passed in as key.
_fullPathCacheDir.emplace(dir, fullpath);
return fullpath;
}

}
}

if(isPopupNotify()){
CCLOG("cocos2d: fullPathForDirectory: No directory found at %s. Possible missing directory.", dir.c_str());
}

// The file wasn't found, return empty string.
return "";
}

std::string FileUtils::fullPathFromRelativeFile(const std::string &filename, const std::string &relativeFile) const
{
return relativeFile.substr(0, relativeFile.rfind('/')+1) + getNewFilename(filename);
Expand Down Expand Up @@ -1053,7 +1107,7 @@ void FileUtils::loadFilenameLookupDictionaryFromFile(const std::string &filename
}
}

std::string FileUtils::getFullPathForDirectoryAndFilename(const std::string& directory, const std::string& filename) const
std::string FileUtils::getFullPathForFilenameWithinDirectory(const std::string& directory, const std::string& filename) const
{
// get directory+filename, safely adding '/' as necessary
std::string ret = directory;
Expand All @@ -1063,7 +1117,7 @@ std::string FileUtils::getFullPathForDirectoryAndFilename(const std::string& dir
ret += filename;

// if the file doesn't exist, return an empty string
if (!isFileExistInternal(ret) && !isDirectoryExistInternal(ret)) {
if (!isFileExistInternal(ret)) {
ret = "";
}
return ret;
Expand Down Expand Up @@ -1122,7 +1176,7 @@ bool FileUtils::isDirectoryExist(const std::string& dirPath) const
for (const auto& resolutionIt : _searchResolutionsOrderArray)
{
// searchPath + file_path + resourceDirectory
fullpath = fullPathForFilename(searchIt + dirPath + resolutionIt);
fullpath = fullPathForDirectory(searchIt + dirPath + resolutionIt);
if (isDirectoryExistInternal(fullpath))
{
_fullPathCache.emplace(dirPath, fullpath);
Expand Down Expand Up @@ -1188,15 +1242,15 @@ void FileUtils::getFileSize(const std::string &filepath, std::function<void(long

void FileUtils::listFilesAsync(const std::string& dirPath, std::function<void(std::vector<std::string>)> callback) const
{
auto fullPath = fullPathForFilename(dirPath);
auto fullPath = fullPathForDirectory(dirPath);
performOperationOffthread([fullPath]() {
return FileUtils::getInstance()->listFiles(fullPath);
}, std::move(callback));
}

void FileUtils::listFilesRecursivelyAsync(const std::string& dirPath, std::function<void(std::vector<std::string>)> callback) const
{
auto fullPath = fullPathForFilename(dirPath);
auto fullPath = fullPathForDirectory(dirPath);
performOperationOffthread([fullPath]() {
std::vector<std::string> retval;
FileUtils::getInstance()->listFilesRecursively(fullPath, &retval);
Expand Down Expand Up @@ -1459,7 +1513,7 @@ long FileUtils::getFileSize(const std::string &filepath) const
std::vector<std::string> FileUtils::listFiles(const std::string& dirPath) const
{
std::vector<std::string> files;
std::string fullpath = fullPathForFilename(dirPath);
std::string fullpath = fullPathForDirectory(dirPath);
if (isDirectoryExist(fullpath))
{
tinydir_dir dir;
Expand Down Expand Up @@ -1497,7 +1551,7 @@ std::vector<std::string> FileUtils::listFiles(const std::string& dirPath) const

void FileUtils::listFilesRecursively(const std::string& dirPath, std::vector<std::string> *files) const
{
std::string fullpath = fullPathForFilename(dirPath);
std::string fullpath = fullPathForDirectory(dirPath);
if (isDirectoryExist(fullpath))
{
tinydir_dir dir;
Expand Down
17 changes: 15 additions & 2 deletions cocos/platform/CCFileUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ class CC_DLL FileUtils
*/
virtual std::string fullPathForFilename(const std::string &filename) const;


/**
* Loads the filenameLookup dictionary from the contents of a filename.
*
Expand Down Expand Up @@ -905,8 +906,14 @@ class CC_DLL FileUtils
* @param filename The name of the file.
* @return The full path of the file, if the file can't be found, it will return an empty string.
*/
virtual std::string getFullPathForDirectoryAndFilename(const std::string& directory, const std::string& filename) const;
virtual std::string getFullPathForFilenameWithinDirectory(const std::string& directory, const std::string& filename) const;


/**
* Returns the fullpath for a given dirname.
* @since 3.17.1
*/
virtual std::string fullPathForDirectory(const std::string &dirname) const;

/**
* mutex used to protect fields.
Expand Down Expand Up @@ -950,11 +957,17 @@ class CC_DLL FileUtils
std::string _defaultResRootPath;

/**
* The full path cache. When a file is found, it will be added into this cache.
* The full path cache for normal files. When a file is found, it will be added into this cache.
* This variable is used for improving the performance of file search.
*/
mutable std::unordered_map<std::string, std::string> _fullPathCache;

/**
* The full path cache for directories. When a diretory is found, it will be added into this cache.
* This variable is used for improving the performance of file search.
*/
mutable std::unordered_map<std::string, std::string> _fullPathCacheDir;

/**
* Writable path.
*/
Expand Down
5 changes: 4 additions & 1 deletion cocos/platform/android/CCFileUtils-android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,16 @@ bool FileUtilsAndroid::isDirectoryExistInternal(const std::string& dirPath) cons
}
else
{


// find it in apk's assets dir
// Found "assets/" at the beginning of the path and we don't want it
//CCLOG("find in apk dirPath(%s)", s);
if (dirPath.find(ASSETS_FOLDER_NAME) == 0)
{
s += ASSETS_FOLDER_NAME_LENGTH;
}

if (FileUtilsAndroid::assetmanager)
{
AAssetDir* aa = AAssetManager_openDir(FileUtilsAndroid::assetmanager, s);
Expand Down Expand Up @@ -295,7 +298,7 @@ std::vector<std::string> FileUtilsAndroid::listFiles(const std::string& dirPath)
if(isAbsolutePath(dirPath)) return FileUtils::listFiles(dirPath);

std::vector<std::string> fileList;
string fullPath = fullPathForFilename(dirPath);
string fullPath = fullPathForDirectory(dirPath);

static const std::string apkprefix("assets/");
string relativePath = "";
Expand Down
2 changes: 2 additions & 0 deletions cocos/platform/android/CCFileUtils-android.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
#include "base/ccTypes.h"
#include <string>
#include <vector>
#include <unordered_map>
#include <memory>
#include "jni.h"
#include "android/asset_manager.h"

Expand Down
2 changes: 1 addition & 1 deletion cocos/platform/apple/CCFileUtils-apple.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class CC_DLL FileUtilsApple : public FileUtils
virtual ~FileUtilsApple();
/* override functions */
virtual std::string getWritablePath() const override;
virtual std::string getFullPathForDirectoryAndFilename(const std::string& directory, const std::string& filename) const override;
virtual std::string getFullPathForFilenameWithinDirectory(const std::string& directory, const std::string& filename) const override;

virtual ValueMap getValueMapFromFile(const std::string& filename) const override;
virtual ValueMap getValueMapFromData(const char* filedata, int filesize) const override;
Expand Down
2 changes: 1 addition & 1 deletion cocos/platform/apple/CCFileUtils-apple.mm
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, str
return true;
}

std::string FileUtilsApple::getFullPathForDirectoryAndFilename(const std::string& directory, const std::string& filename) const
std::string FileUtilsApple::getFullPathForFilenameWithinDirectory(const std::string& directory, const std::string& filename) const
{
if (directory[0] != '/')
{
Expand Down
6 changes: 3 additions & 3 deletions cocos/platform/win32/CCFileUtils-win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,12 @@ std::string FileUtilsWin32::getPathForFilename(const std::string& filename, cons
return FileUtils::getPathForFilename(unixFileName, unixResolutionDirectory, unixSearchPath);
}

std::string FileUtilsWin32::getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename) const
std::string FileUtilsWin32::getFullPathForFilenameWithinDirectory(const std::string& strDirectory, const std::string& strFilename) const
{
std::string unixDirectory = convertPathFormatToUnixStyle(strDirectory);
std::string unixFilename = convertPathFormatToUnixStyle(strFilename);

return FileUtils::getFullPathForDirectoryAndFilename(unixDirectory, unixFilename);
return FileUtils::getFullPathForFilenameWithinDirectory(unixDirectory, unixFilename);
}

void FileUtilsWin32::listFilesRecursively(const std::string& dirPath, std::vector<std::string> *files) const
Expand Down Expand Up @@ -286,7 +286,7 @@ long FileUtilsWin32::getFileSize(const std::string &filepath) const

std::vector<std::string> FileUtilsWin32::listFiles(const std::string& dirPath) const
{
std::string fullpath = fullPathForFilename(dirPath);
std::string fullpath = fullPathForDirectory(dirPath);
std::vector<std::string> files;
if (isDirectoryExist(fullpath))
{
Expand Down
2 changes: 1 addition & 1 deletion cocos/platform/win32/CCFileUtils-win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class CC_DLL FileUtilsWin32 : public FileUtils
* @param filename The name of the file.
* @return The full path of the file, if the file can't be found, it will return an empty string.
*/
virtual std::string getFullPathForDirectoryAndFilename(const std::string& directory, const std::string& filename) const override;
virtual std::string getFullPathForFilenameWithinDirectory(const std::string& directory, const std::string& filename) const override;

/**
* List all files in a directory.
Expand Down
8 changes: 4 additions & 4 deletions cocos/platform/winrt/CCFileUtilsWinRT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,11 @@ std::string CCFileUtilsWinRT::getPathForFilename(const std::string& filename, co
return FileUtils::getPathForFilename(unixFileName, unixResolutionDirectory, unixSearchPath);
}

std::string CCFileUtilsWinRT::getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename) const
std::string CCFileUtilsWinRT::getFullPathForFilenameWithinDirectory(const std::string& strDirectory, const std::string& strFilename) const
{
std::string unixDirectory = convertPathFormatToUnixStyle(strDirectory);
std::string unixFilename = convertPathFormatToUnixStyle(strFilename);
return FileUtils::getFullPathForDirectoryAndFilename(unixDirectory, unixFilename);
return FileUtils::getFullPathForFilenameWithinDirectory(unixDirectory, unixFilename);
}

std::string CCFileUtilsWinRT::getSuitableFOpen(const std::string& filenameUtf8) const
Expand Down Expand Up @@ -380,7 +380,7 @@ string CCFileUtilsWinRT::getWritablePath() const

void CCFileUtilsWinRT::listFilesRecursively(const std::string& dirPath, std::vector<std::string> *files) const
{
std::string fullpath = fullPathForFilename(dirPath);
std::string fullpath = fullPathForDirectory(dirPath);
if (isDirectoryExist(fullpath))
{
tinydir_dir dir;
Expand Down Expand Up @@ -426,7 +426,7 @@ void CCFileUtilsWinRT::listFilesRecursively(const std::string& dirPath, std::vec

std::vector<std::string> CCFileUtilsWinRT::listFiles(const std::string& dirPath) const
{
std::string fullpath = fullPathForFilename(dirPath);
std::string fullpath = fullPathForDirectory(dirPath);
std::vector<std::string> files;
if (isDirectoryExist(fullpath))
{
Expand Down
2 changes: 1 addition & 1 deletion cocos/platform/winrt/CCFileUtilsWinRT.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class CC_DLL CCFileUtilsWinRT : public FileUtils
virtual std::string getWritablePath() const;
virtual bool isAbsolutePath(const std::string& strPath) const;
virtual std::string getPathForFilename(const std::string& filename, const std::string& resolutionDirectory, const std::string& searchPath) const override;
virtual std::string getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename) const override;
virtual std::string getFullPathForFilenameWithinDirectory(const std::string& strDirectory, const std::string& strFilename) const override;
virtual std::string getSuitableFOpen(const std::string& filenameUtf8) const override;
virtual long getFileSize(const std::string &filepath) override;
virtual FileUtils::Status getContents(const std::string& filename, ResizableBuffer* buffer) override;
Expand Down
38 changes: 38 additions & 0 deletions tests/cpp-tests/Classes/FileUtilsTest/FileUtilsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ FileUtilsTests::FileUtilsTests()
ADD_TEST_CASE(TestFileFuncsAsync);
ADD_TEST_CASE(TestWriteStringAsync);
ADD_TEST_CASE(TestWriteDataAsync);
ADD_TEST_CASE(TestListFiles);
}

// TestResolutionDirectories
Expand Down Expand Up @@ -1391,3 +1392,40 @@ std::string TestWriteDataAsync::subtitle() const
{
return "";
}

void TestListFiles::onEnter()
{
FileUtilsDemo::onEnter();

auto winSize = Director::getInstance()->getWinSize();

auto infoLabel = Label::createWithTTF("show file count, should not be 0", "fonts/Thonburi.ttf", 18);
this->addChild(infoLabel);
infoLabel->setPosition(winSize.width / 2, winSize.height * 3 / 4);

auto cntLabel = Label::createWithTTF("show readResult", "fonts/Thonburi.ttf", 18);
this->addChild(cntLabel);
cntLabel->setPosition(winSize.width / 2, winSize.height / 3);
// writeTest
auto list = FileUtils::getInstance()->listFiles("fonts");

char cntBuffer[200] = { 0 };
snprintf(cntBuffer, 200, "%d", list.size());
cntLabel->setString(cntBuffer);

}

void TestListFiles::onExit()
{
FileUtilsDemo::onExit();
}

std::string TestListFiles::title() const
{
return "FileUtils: list files of directory";
}

std::string TestListFiles::subtitle() const
{
return "";
}
11 changes: 11 additions & 0 deletions tests/cpp-tests/Classes/FileUtilsTest/FileUtilsTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,15 @@ class TestWriteDataAsync : public FileUtilsDemo
virtual std::string subtitle() const override;
};

class TestListFiles : public FileUtilsDemo
{
public:
CREATE_FUNC(TestListFiles);

virtual void onEnter() override;
virtual void onExit() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
};

#endif /* __FILEUTILSTEST_H__ */