[FileAccess] Implement get_size and get_access_time methods.
This commit is contained in:
committed by
Pāvels Nadtočajevs
parent
b5bdb88062
commit
85d3be8070
@ -132,6 +132,10 @@ uint64_t FileAccessAndroid::get_buffer(uint8_t *p_dst, uint64_t p_length) const
|
||||
return r;
|
||||
}
|
||||
|
||||
int64_t FileAccessAndroid::_get_size(const String &p_file) {
|
||||
return AAsset_getLength64(asset);
|
||||
}
|
||||
|
||||
Error FileAccessAndroid::get_error() const {
|
||||
return eof ? ERR_FILE_EOF : OK; // not sure what else it may happen
|
||||
}
|
||||
|
||||
@ -77,6 +77,8 @@ public:
|
||||
virtual bool file_exists(const String &p_path) override; // return true if a file exists
|
||||
|
||||
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; }
|
||||
virtual uint64_t _get_access_time(const String &p_file) override { return 0; }
|
||||
virtual int64_t _get_size(const String &p_file) override;
|
||||
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
|
||||
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return ERR_UNAVAILABLE; }
|
||||
|
||||
|
||||
@ -53,7 +53,9 @@ jmethodID FileAccessFilesystemJAndroid::_file_write = nullptr;
|
||||
jmethodID FileAccessFilesystemJAndroid::_file_flush = nullptr;
|
||||
jmethodID FileAccessFilesystemJAndroid::_file_exists = nullptr;
|
||||
jmethodID FileAccessFilesystemJAndroid::_file_last_modified = nullptr;
|
||||
jmethodID FileAccessFilesystemJAndroid::_file_last_accessed = nullptr;
|
||||
jmethodID FileAccessFilesystemJAndroid::_file_resize = nullptr;
|
||||
jmethodID FileAccessFilesystemJAndroid::_file_size = nullptr;
|
||||
|
||||
String FileAccessFilesystemJAndroid::get_path() const {
|
||||
return path_src;
|
||||
@ -300,7 +302,7 @@ bool FileAccessFilesystemJAndroid::file_exists(const String &p_path) {
|
||||
uint64_t FileAccessFilesystemJAndroid::_get_modified_time(const String &p_file) {
|
||||
if (_file_last_modified) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, false);
|
||||
ERR_FAIL_NULL_V(env, 0);
|
||||
|
||||
String path = fix_path(p_file).simplify_path();
|
||||
jstring js = env->NewStringUTF(path.utf8().get_data());
|
||||
@ -312,6 +314,36 @@ uint64_t FileAccessFilesystemJAndroid::_get_modified_time(const String &p_file)
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t FileAccessFilesystemJAndroid::_get_access_time(const String &p_file) {
|
||||
if (_file_last_accessed) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, 0);
|
||||
|
||||
String path = fix_path(p_file).simplify_path();
|
||||
jstring js = env->NewStringUTF(path.utf8().get_data());
|
||||
uint64_t result = env->CallLongMethod(file_access_handler, _file_last_accessed, js);
|
||||
env->DeleteLocalRef(js);
|
||||
return result;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t FileAccessFilesystemJAndroid::_get_size(const String &p_file) {
|
||||
if (_file_size) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, -1);
|
||||
|
||||
String path = fix_path(p_file).simplify_path();
|
||||
jstring js = env->NewStringUTF(path.utf8().get_data());
|
||||
int64_t result = env->CallLongMethod(file_access_handler, _file_size, js);
|
||||
env->DeleteLocalRef(js);
|
||||
return result;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void FileAccessFilesystemJAndroid::setup(jobject p_file_access_handler) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
file_access_handler = env->NewGlobalRef(p_file_access_handler);
|
||||
@ -332,7 +364,9 @@ void FileAccessFilesystemJAndroid::setup(jobject p_file_access_handler) {
|
||||
_file_flush = env->GetMethodID(cls, "fileFlush", "(I)V");
|
||||
_file_exists = env->GetMethodID(cls, "fileExists", "(Ljava/lang/String;)Z");
|
||||
_file_last_modified = env->GetMethodID(cls, "fileLastModified", "(Ljava/lang/String;)J");
|
||||
_file_last_accessed = env->GetMethodID(cls, "fileLastAccessed", "(Ljava/lang/String;)J");
|
||||
_file_resize = env->GetMethodID(cls, "fileResize", "(IJ)I");
|
||||
_file_size = env->GetMethodID(cls, "fileSize", "(Ljava/lang/String;)J");
|
||||
}
|
||||
|
||||
void FileAccessFilesystemJAndroid::terminate() {
|
||||
|
||||
@ -51,7 +51,9 @@ class FileAccessFilesystemJAndroid : public FileAccess {
|
||||
static jmethodID _file_close;
|
||||
static jmethodID _file_exists;
|
||||
static jmethodID _file_last_modified;
|
||||
static jmethodID _file_last_accessed;
|
||||
static jmethodID _file_resize;
|
||||
static jmethodID _file_size;
|
||||
|
||||
int id;
|
||||
String absolute_path;
|
||||
@ -91,6 +93,8 @@ public:
|
||||
static void terminate();
|
||||
|
||||
virtual uint64_t _get_modified_time(const String &p_file) override;
|
||||
virtual uint64_t _get_access_time(const String &p_file) override;
|
||||
virtual int64_t _get_size(const String &p_file) override;
|
||||
virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
|
||||
virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return ERR_UNAVAILABLE; }
|
||||
|
||||
|
||||
@ -66,6 +66,8 @@ internal class AssetData(context: Context, private val filePath: String, accessF
|
||||
}
|
||||
|
||||
fun fileLastModified(path: String) = 0L
|
||||
fun fileLastAccessed(path: String) = 0L
|
||||
fun fileSize(path: String) = -1L
|
||||
|
||||
fun delete(path: String) = false
|
||||
|
||||
|
||||
@ -132,6 +132,24 @@ internal abstract class DataAccess {
|
||||
}
|
||||
}
|
||||
|
||||
fun fileLastAccessed(storageScope: StorageScope, context: Context, path: String): Long {
|
||||
return when(storageScope) {
|
||||
StorageScope.APP -> FileData.fileLastAccessed(path)
|
||||
StorageScope.ASSETS -> AssetData.fileLastAccessed(path)
|
||||
StorageScope.SHARED -> MediaStoreData.fileLastAccessed(context, path)
|
||||
StorageScope.UNKNOWN -> 0L
|
||||
}
|
||||
}
|
||||
|
||||
fun fileSize(storageScope: StorageScope, context: Context, path: String): Long {
|
||||
return when(storageScope) {
|
||||
StorageScope.APP -> FileData.fileSize(path)
|
||||
StorageScope.ASSETS -> AssetData.fileSize(path)
|
||||
StorageScope.SHARED -> MediaStoreData.fileSize(context, path)
|
||||
StorageScope.UNKNOWN -> -1L
|
||||
}
|
||||
}
|
||||
|
||||
fun removeFile(storageScope: StorageScope, context: Context, path: String): Boolean {
|
||||
return when(storageScope) {
|
||||
StorageScope.APP -> FileData.delete(path)
|
||||
|
||||
@ -228,6 +228,21 @@ class FileAccessHandler(val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
fun fileLastAccessed(filepath: String?): Long {
|
||||
val storageScope = storageScopeIdentifier.identifyStorageScope(filepath)
|
||||
if (storageScope == StorageScope.UNKNOWN) {
|
||||
return 0L
|
||||
}
|
||||
|
||||
return try {
|
||||
filepath?.let {
|
||||
DataAccess.fileLastAccessed(storageScope, context, it)
|
||||
} ?: 0L
|
||||
} catch (e: SecurityException) {
|
||||
0L
|
||||
}
|
||||
}
|
||||
|
||||
fun fileResize(fileId: Int, length: Long): Int {
|
||||
if (!hasFileId(fileId)) {
|
||||
return Error.FAILED.toNativeValue()
|
||||
@ -236,6 +251,21 @@ class FileAccessHandler(val context: Context) {
|
||||
return files[fileId].resize(length).toNativeValue()
|
||||
}
|
||||
|
||||
fun fileSize(filepath: String?): Long {
|
||||
val storageScope = storageScopeIdentifier.identifyStorageScope(filepath)
|
||||
if (storageScope == StorageScope.UNKNOWN) {
|
||||
return -1L
|
||||
}
|
||||
|
||||
return try {
|
||||
filepath?.let {
|
||||
DataAccess.fileSize(storageScope, context, it)
|
||||
} ?: -1L
|
||||
} catch (e: SecurityException) {
|
||||
-1L
|
||||
}
|
||||
}
|
||||
|
||||
fun fileGetPosition(fileId: Int): Long {
|
||||
if (!hasFileId(fileId)) {
|
||||
return 0L
|
||||
|
||||
@ -30,10 +30,16 @@
|
||||
|
||||
package org.godotengine.godot.io.file
|
||||
|
||||
import android.os.*
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.RandomAccessFile
|
||||
import java.nio.channels.FileChannel
|
||||
import java.nio.file.attribute.BasicFileAttributes
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* Implementation of [DataAccess] which handles regular (not scoped) file access and interactions.
|
||||
@ -59,6 +65,30 @@ internal class FileData(filePath: String, accessFlag: FileAccessFlags) : DataAcc
|
||||
}
|
||||
}
|
||||
|
||||
fun fileLastAccessed(filepath: String): Long {
|
||||
return try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
Files.readAttributes<BasicFileAttributes>(FileSystems.getDefault().getPath(filepath), BasicFileAttributes::class.java).lastAccessTime().to(TimeUnit.SECONDS)
|
||||
} else {
|
||||
0L
|
||||
}
|
||||
} catch (e: SecurityException) {
|
||||
0L
|
||||
}
|
||||
}
|
||||
|
||||
fun fileSize(filepath: String): Long {
|
||||
return try {
|
||||
if (File(filepath).isFile) {
|
||||
File(filepath).length()
|
||||
} else {
|
||||
-1L
|
||||
}
|
||||
} catch (e: SecurityException) {
|
||||
-1L
|
||||
}
|
||||
}
|
||||
|
||||
fun delete(filepath: String): Boolean {
|
||||
return try {
|
||||
File(filepath).delete()
|
||||
|
||||
@ -212,6 +212,20 @@ internal class MediaStoreData(context: Context, filePath: String, accessFlag: Fi
|
||||
return dataItem.dateModified.toLong() / 1000L
|
||||
}
|
||||
|
||||
fun fileLastAccessed(@Suppress("UNUSED_PARAMETER") context: Context, @Suppress("UNUSED_PARAMETER") path: String): Long {
|
||||
return 0L
|
||||
}
|
||||
|
||||
fun fileSize(context: Context, path: String): Long {
|
||||
val result = queryByPath(context, path)
|
||||
if (result.isEmpty()) {
|
||||
return -1L
|
||||
}
|
||||
|
||||
val dataItem = result[0]
|
||||
return dataItem.size.toLong()
|
||||
}
|
||||
|
||||
fun rename(context: Context, from: String, to: String): Boolean {
|
||||
// Ensure the source exists.
|
||||
val sources = queryByPath(context, from)
|
||||
|
||||
Reference in New Issue
Block a user