diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 34e55741567..da1678d1149 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -2331,6 +2331,17 @@ uint64_t _File::get_modified_time(const String &p_file) const { return FileAccess::get_modified_time(p_file); } + +void _File::update_access_time(const String &p_file) const { + FileAccess::update_access_time(p_file); +} + + +Dictionary _File::get_file_statistics(const String &p_file) const { + + return FileAccess::get_file_statistics(p_file); +} + void _File::_bind_methods() { ClassDB::bind_method(D_METHOD("open_encrypted", "path", "mode_flags", "key"), &_File::open_encrypted); @@ -2384,6 +2395,8 @@ void _File::_bind_methods() { ClassDB::bind_method(D_METHOD("file_exists", "path"), &_File::file_exists); ClassDB::bind_method(D_METHOD("get_modified_time", "file"), &_File::get_modified_time); + ClassDB::bind_method(D_METHOD("get_file_statistics", "file"), &_File::get_file_statistics); + ClassDB::bind_method(D_METHOD("update_access_time", "file"), &_File::update_access_time); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "endian_swap"), "set_endian_swap", "get_endian_swap"); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 1df2c799c46..7908c07af65 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -576,6 +576,9 @@ class _File : public Reference { bool file_exists(const String &p_name) const; // Return true if a file exists. uint64_t get_modified_time(const String &p_file) const; + Dictionary get_file_statistics(const String &p_file) const; + void update_access_time(const String &p_file) const; + _File(); virtual ~_File(); diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index 12c809a8c9b..224748fd324 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -493,6 +493,32 @@ void FileAccess::store_double(double p_dest) { store_64(m.l); }; + +void FileAccess::update_access_time(const String &p_file) { + + if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) + return ; + + FileAccess *fa = create_for_path(p_file); + ERR_FAIL_COND_MSG(!fa, "Cannot create FileAccess for path '" + p_file + "'."); + + fa->_update_access_time(p_file); + memdelete(fa); +} + +Dictionary FileAccess::get_file_statistics(const String &p_file) { + + if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) + return Dictionary(); + + FileAccess *fa = create_for_path(p_file); + ERR_FAIL_COND_V_MSG(!fa, Dictionary(), "Cannot create FileAccess for path '" + p_file + "'."); + + Dictionary stat = fa->_get_file_statistics(p_file); + memdelete(fa); + return stat; +} + uint64_t FileAccess::get_modified_time(const String &p_file) { if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) diff --git a/core/os/file_access.h b/core/os/file_access.h index 30ccf5667b5..e1ad7fe39fb 100644 --- a/core/os/file_access.h +++ b/core/os/file_access.h @@ -35,6 +35,7 @@ #include "core/os/memory.h" #include "core/typedefs.h" #include "core/ustring.h" +#include "core/dictionary.h" /** * Multi-Platform abstraction for accessing to files. @@ -63,6 +64,8 @@ class FileAccess { String fix_path(const String &p_path) const; virtual Error _open(const String &p_path, int p_mode_flags) = 0; ///< open a file virtual uint64_t _get_modified_time(const String &p_file) = 0; + virtual Dictionary _get_file_statistics(const String &p_file) { return Dictionary(); }; + virtual void _update_access_time(const String &p_file) { }; static FileCloseFailNotify close_fail_notify; @@ -157,6 +160,8 @@ class FileAccess { static CreateFunc get_create_func(AccessType p_access); static bool exists(const String &p_name); ///< return true if a file exists static uint64_t get_modified_time(const String &p_file); + static Dictionary get_file_statistics(const String &p_file); + static void update_access_time(const String &p_file); static uint32_t get_unix_permissions(const String &p_file); static Error set_unix_permissions(const String &p_file, uint32_t p_permissions); diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index aac1b5a7da1..4bc845e80c7 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -37,6 +37,7 @@ #include #include +#include #include @@ -310,6 +311,29 @@ bool FileAccessUnix::file_exists(const String &p_path) { } } +Dictionary FileAccessUnix::_get_file_statistics(const String &p_file) { + + String file = fix_path(p_file); + struct stat flags; + int err = stat(file.utf8().get_data(), &flags); + + if (!err) { + Dictionary file_stat = Dictionary(); + file_stat["mode"] = Variant(flags.st_mode); + file_stat["atime"] = Variant((int64_t)flags.st_atime); + file_stat["mtime"] = Variant((int64_t)flags.st_mtime); + file_stat["size"] = Variant(flags.st_size); + return file_stat; + } else { + ERR_FAIL_V_MSG(Dictionary(), "Failed to get stat flags for: " + p_file + "."); + }; +} + +void FileAccessUnix::_update_access_time(const String &p_file) { + String file = fix_path(p_file); + utime(file.utf8().get_data(), 0); +} + uint64_t FileAccessUnix::_get_modified_time(const String &p_file) { String file = fix_path(p_file); diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h index 0cbf379065b..7c562997d92 100644 --- a/drivers/unix/file_access_unix.h +++ b/drivers/unix/file_access_unix.h @@ -81,6 +81,9 @@ class FileAccessUnix : public FileAccess { virtual bool file_exists(const String &p_path); ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file); + virtual Dictionary _get_file_statistics(const String &p_file); + virtual void _update_access_time(const String &p_file); + virtual uint32_t _get_unix_permissions(const String &p_file); virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions);