Просмотр исходного кода

android: Convert FileUtil to Kotlin

Charles Lombardo 3 лет назад
Родитель
Сommit
7b54c2b2e2

+ 0 - 296
src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.java

@@ -1,296 +0,0 @@
-package org.yuzu.yuzu_emu.utils;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.provider.DocumentsContract;
-
-import androidx.annotation.Nullable;
-import androidx.documentfile.provider.DocumentFile;
-
-import org.yuzu.yuzu_emu.model.MinimalDocumentFile;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.List;
-
-public class FileUtil {
-    static final String PATH_TREE = "tree";
-    static final String DECODE_METHOD = "UTF-8";
-    static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
-    static final String TEXT_PLAIN = "text/plain";
-
-    /**
-     * Create a file from directory with filename.
-     * @param context Application context
-     * @param directory parent path for file.
-     * @param filename file display name.
-     * @return boolean
-     */
-    @Nullable
-    public static DocumentFile createFile(Context context, String directory, String filename) {
-        try {
-            Uri directoryUri = Uri.parse(directory);
-            DocumentFile parent = DocumentFile.fromTreeUri(context, directoryUri);
-            if (parent == null) return null;
-            filename = URLDecoder.decode(filename, DECODE_METHOD);
-            String mimeType = APPLICATION_OCTET_STREAM;
-            if (filename.endsWith(".txt")) {
-                mimeType = TEXT_PLAIN;
-            }
-            DocumentFile exists = parent.findFile(filename);
-            if (exists != null) return exists;
-            return parent.createFile(mimeType, filename);
-        } catch (Exception e) {
-            Log.error("[FileUtil]: Cannot create file, error: " + e.getMessage());
-        }
-        return null;
-    }
-
-    /**
-     * Create a directory from directory with filename.
-     * @param context Application context
-     * @param directory parent path for directory.
-     * @param directoryName directory display name.
-     * @return boolean
-     */
-    @Nullable
-    public static DocumentFile createDir(Context context, String directory, String directoryName) {
-        try {
-            Uri directoryUri = Uri.parse(directory);
-            DocumentFile parent = DocumentFile.fromTreeUri(context, directoryUri);
-            if (parent == null) return null;
-            directoryName = URLDecoder.decode(directoryName, DECODE_METHOD);
-            DocumentFile isExist = parent.findFile(directoryName);
-            if (isExist != null) return isExist;
-            return parent.createDirectory(directoryName);
-        } catch (Exception e) {
-            Log.error("[FileUtil]: Cannot create file, error: " + e.getMessage());
-        }
-        return null;
-    }
-
-    /**
-     * Open content uri and return file descriptor to JNI.
-     * @param context Application context
-     * @param path Native content uri path
-     * @param openmode will be one of "r", "r", "rw", "wa", "rwa"
-     * @return file descriptor
-     */
-    public static int openContentUri(Context context, String path, String openmode) {
-        try {
-            Uri uri = Uri.parse(path);
-            ParcelFileDescriptor parcelFileDescriptor = context.getContentResolver().openFileDescriptor(uri, openmode);
-            if (parcelFileDescriptor == null) {
-                Log.error("[FileUtil]: Cannot get the file descriptor from uri: " + path);
-                return -1;
-            }
-            return parcelFileDescriptor.detachFd();
-        }
-        catch (Exception e) {
-            Log.error("[FileUtil]: Cannot open content uri, error: " + e.getMessage());
-        }
-        return -1;
-    }
-
-    /**
-     * Reference:  https://stackoverflow.com/questions/42186820/documentfile-is-very-slow
-     * This function will be faster than DoucmentFile.listFiles
-     * @param context Application context
-     * @param uri Directory uri.
-     * @return CheapDocument lists.
-     */
-    public static MinimalDocumentFile[] listFiles(Context context, Uri uri) {
-        final ContentResolver resolver = context.getContentResolver();
-        final String[] columns = new String[]{
-                DocumentsContract.Document.COLUMN_DOCUMENT_ID,
-                DocumentsContract.Document.COLUMN_DISPLAY_NAME,
-                DocumentsContract.Document.COLUMN_MIME_TYPE,
-        };
-        Cursor c = null;
-        final List<MinimalDocumentFile> results = new ArrayList<>();
-        try {
-            String docId;
-            if (isRootTreeUri(uri)) {
-                docId = DocumentsContract.getTreeDocumentId(uri);
-            } else {
-                docId = DocumentsContract.getDocumentId(uri);
-            }
-            final Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri, docId);
-            c = resolver.query(childrenUri, columns, null, null, null);
-            while(c.moveToNext()) {
-                final String documentId = c.getString(0);
-                final String documentName = c.getString(1);
-                final String documentMimeType = c.getString(2);
-                final Uri documentUri = DocumentsContract.buildDocumentUriUsingTree(uri, documentId);
-                MinimalDocumentFile document = new MinimalDocumentFile(documentName, documentMimeType, documentUri);
-                results.add(document);
-            }
-        } catch (Exception e) {
-            Log.error("[FileUtil]: Cannot list file error: " + e.getMessage());
-        } finally {
-            closeQuietly(c);
-        }
-        return results.toArray(new MinimalDocumentFile[0]);
-    }
-
-    /**
-     * Check whether given path exists.
-     * @param path Native content uri path
-     * @return bool
-     */
-    public static boolean Exists(Context context, String path) {
-        Cursor c = null;
-        try {
-            Uri mUri = Uri.parse(path);
-            final String[] columns = new String[] { DocumentsContract.Document.COLUMN_DOCUMENT_ID };
-            c = context.getContentResolver().query(mUri, columns, null, null, null);
-            return c.getCount() > 0;
-        } catch (Exception e) {
-            Log.info("[FileUtil] Cannot find file from given path, error: " + e.getMessage());
-        } finally {
-            closeQuietly(c);
-        }
-        return false;
-    }
-
-    /**
-     * Check whether given path is a directory
-     * @param path content uri path
-     * @return bool
-     */
-    public static boolean isDirectory(Context context, String path) {
-        final ContentResolver resolver = context.getContentResolver();
-        final String[] columns = new String[] {
-                DocumentsContract.Document.COLUMN_MIME_TYPE
-        };
-        boolean isDirectory = false;
-        Cursor c = null;
-        try {
-            Uri mUri = Uri.parse(path);
-            c = resolver.query(mUri, columns, null, null, null);
-            c.moveToNext();
-            final String mimeType = c.getString(0);
-            isDirectory = mimeType.equals(DocumentsContract.Document.MIME_TYPE_DIR);
-        } catch (Exception e) {
-            Log.error("[FileUtil]: Cannot list files, error: " + e.getMessage());
-        } finally {
-            closeQuietly(c);
-        }
-        return isDirectory;
-    }
-
-    /**
-     * Get file display name from given path
-     * @param path content uri path
-     * @return String display name
-     */
-    public static String getFilename(Context context, String path) {
-        final ContentResolver resolver = context.getContentResolver();
-        final String[] columns = new String[] {
-                DocumentsContract.Document.COLUMN_DISPLAY_NAME
-        };
-        String filename = "";
-        Cursor c = null;
-        try {
-            Uri mUri = Uri.parse(path);
-            c = resolver.query(mUri, columns, null, null, null);
-            c.moveToNext();
-            filename = c.getString(0);
-        } catch (Exception e) {
-            Log.error("[FileUtil]: Cannot get file size, error: " + e.getMessage());
-        } finally {
-            closeQuietly(c);
-        }
-        return filename;
-    }
-
-    public static String[] getFilesName(Context context, String path) {
-        Uri uri = Uri.parse(path);
-        List<String> files = new ArrayList<>();
-        for (MinimalDocumentFile file: FileUtil.listFiles(context, uri)) {
-            files.add(file.getFilename());
-        }
-        return files.toArray(new String[0]);
-    }
-
-    /**
-     * Get file size from given path.
-     * @param path content uri path
-     * @return long file size
-     */
-    public static long getFileSize(Context context, String path) {
-        final ContentResolver resolver = context.getContentResolver();
-        final String[] columns = new String[] {
-                DocumentsContract.Document.COLUMN_SIZE
-        };
-        long size = 0;
-        Cursor c =null;
-        try {
-            Uri mUri = Uri.parse(path);
-            c = resolver.query(mUri, columns, null, null, null);
-            c.moveToNext();
-            size = c.getLong(0);
-        } catch (Exception e) {
-            Log.error("[FileUtil]: Cannot get file size, error: " + e.getMessage());
-        } finally {
-            closeQuietly(c);
-        }
-        return size;
-    }
-
-    public static boolean copyUriToInternalStorage(Context context, Uri sourceUri, String destinationParentPath, String destinationFilename) {
-        InputStream input = null;
-        FileOutputStream output = null;
-        try {
-            input = context.getContentResolver().openInputStream(sourceUri);
-            output = new FileOutputStream(destinationParentPath + "/" + destinationFilename);
-            byte[] buffer = new byte[1024];
-            int len;
-            while ((len = input.read(buffer)) != -1) {
-                output.write(buffer, 0, len);
-            }
-            output.flush();
-            return true;
-        } catch (Exception e) {
-            Log.error("[FileUtil]: Cannot copy file, error: " + e.getMessage());
-        } finally {
-            if (input != null) {
-                try {
-                    input.close();
-                } catch (IOException e) {
-                    Log.error("[FileUtil]: Cannot close input file, error: " + e.getMessage());
-                }
-            }
-            if (output != null) {
-                try {
-                    output.close();
-                } catch (IOException e) {
-                    Log.error("[FileUtil]: Cannot close output file, error: " + e.getMessage());
-                }
-            }
-        }
-        return false;
-    }
-
-    public static boolean isRootTreeUri(Uri uri) {
-        final List<String> paths = uri.getPathSegments();
-        return paths.size() == 2 && PATH_TREE.equals(paths.get(0));
-    }
-
-    public static void closeQuietly(AutoCloseable closeable) {
-        if (closeable != null) {
-            try {
-                closeable.close();
-            } catch (RuntimeException rethrown) {
-                throw rethrown;
-            } catch (Exception ignored) {
-            }
-        }
-    }
-}

+ 292 - 0
src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt

@@ -0,0 +1,292 @@
+package org.yuzu.yuzu_emu.utils
+
+import android.content.Context
+import android.database.Cursor
+import android.net.Uri
+import android.provider.DocumentsContract
+import androidx.documentfile.provider.DocumentFile
+import org.yuzu.yuzu_emu.model.MinimalDocumentFile
+import java.io.FileOutputStream
+import java.io.IOException
+import java.io.InputStream
+import java.net.URLDecoder
+
+object FileUtil {
+    const val PATH_TREE = "tree"
+    const val DECODE_METHOD = "UTF-8"
+    const val APPLICATION_OCTET_STREAM = "application/octet-stream"
+    const val TEXT_PLAIN = "text/plain"
+
+    /**
+     * Create a file from directory with filename.
+     * @param context Application context
+     * @param directory parent path for file.
+     * @param filename file display name.
+     * @return boolean
+     */
+    fun createFile(context: Context?, directory: String?, filename: String): DocumentFile? {
+        var decodedFilename = filename
+        try {
+            val directoryUri = Uri.parse(directory)
+            val parent = DocumentFile.fromTreeUri(context!!, directoryUri) ?: return null
+            decodedFilename = URLDecoder.decode(decodedFilename, DECODE_METHOD)
+            var mimeType = APPLICATION_OCTET_STREAM
+            if (decodedFilename.endsWith(".txt")) {
+                mimeType = TEXT_PLAIN
+            }
+            val exists = parent.findFile(decodedFilename)
+            return exists ?: parent.createFile(mimeType, decodedFilename)
+        } catch (e: Exception) {
+            Log.error("[FileUtil]: Cannot create file, error: " + e.message)
+        }
+        return null
+    }
+
+    /**
+     * Create a directory from directory with filename.
+     * @param context Application context
+     * @param directory parent path for directory.
+     * @param directoryName directory display name.
+     * @return boolean
+     */
+    fun createDir(context: Context?, directory: String?, directoryName: String?): DocumentFile? {
+        var decodedDirectoryName = directoryName
+        try {
+            val directoryUri = Uri.parse(directory)
+            val parent = DocumentFile.fromTreeUri(context!!, directoryUri) ?: return null
+            decodedDirectoryName = URLDecoder.decode(decodedDirectoryName, DECODE_METHOD)
+            val isExist = parent.findFile(decodedDirectoryName)
+            return isExist ?: parent.createDirectory(decodedDirectoryName)
+        } catch (e: Exception) {
+            Log.error("[FileUtil]: Cannot create file, error: " + e.message)
+        }
+        return null
+    }
+
+    /**
+     * Open content uri and return file descriptor to JNI.
+     * @param context Application context
+     * @param path Native content uri path
+     * @param openMode will be one of "r", "r", "rw", "wa", "rwa"
+     * @return file descriptor
+     */
+    @JvmStatic
+    fun openContentUri(context: Context, path: String, openMode: String?): Int {
+        try {
+            val uri = Uri.parse(path)
+            val parcelFileDescriptor = context.contentResolver.openFileDescriptor(uri, openMode!!)
+            if (parcelFileDescriptor == null) {
+                Log.error("[FileUtil]: Cannot get the file descriptor from uri: $path")
+                return -1
+            }
+            val fileDescriptor = parcelFileDescriptor.detachFd()
+            parcelFileDescriptor.close()
+            return fileDescriptor
+        } catch (e: Exception) {
+            Log.error("[FileUtil]: Cannot open content uri, error: " + e.message)
+        }
+        return -1
+    }
+
+    /**
+     * Reference:  https://stackoverflow.com/questions/42186820/documentfile-is-very-slow
+     * This function will be faster than DoucmentFile.listFiles
+     * @param context Application context
+     * @param uri Directory uri.
+     * @return CheapDocument lists.
+     */
+    fun listFiles(context: Context, uri: Uri): Array<MinimalDocumentFile> {
+        val resolver = context.contentResolver
+        val columns = arrayOf(
+            DocumentsContract.Document.COLUMN_DOCUMENT_ID,
+            DocumentsContract.Document.COLUMN_DISPLAY_NAME,
+            DocumentsContract.Document.COLUMN_MIME_TYPE
+        )
+        var c: Cursor? = null
+        val results: MutableList<MinimalDocumentFile> = ArrayList()
+        try {
+            val docId: String = if (isRootTreeUri(uri)) {
+                DocumentsContract.getTreeDocumentId(uri)
+            } else {
+                DocumentsContract.getDocumentId(uri)
+            }
+            val childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri, docId)
+            c = resolver.query(childrenUri, columns, null, null, null)
+            while (c!!.moveToNext()) {
+                val documentId = c.getString(0)
+                val documentName = c.getString(1)
+                val documentMimeType = c.getString(2)
+                val documentUri = DocumentsContract.buildDocumentUriUsingTree(uri, documentId)
+                val document = MinimalDocumentFile(documentName, documentMimeType, documentUri)
+                results.add(document)
+            }
+        } catch (e: Exception) {
+            Log.error("[FileUtil]: Cannot list file error: " + e.message)
+        } finally {
+            closeQuietly(c)
+        }
+        return results.toTypedArray()
+    }
+
+    /**
+     * Check whether given path exists.
+     * @param path Native content uri path
+     * @return bool
+     */
+    fun exists(context: Context, path: String?): Boolean {
+        var c: Cursor? = null
+        try {
+            val mUri = Uri.parse(path)
+            val columns = arrayOf(DocumentsContract.Document.COLUMN_DOCUMENT_ID)
+            c = context.contentResolver.query(mUri, columns, null, null, null)
+            return c!!.count > 0
+        } catch (e: Exception) {
+            Log.info("[FileUtil] Cannot find file from given path, error: " + e.message)
+        } finally {
+            closeQuietly(c)
+        }
+        return false
+    }
+
+    /**
+     * Check whether given path is a directory
+     * @param path content uri path
+     * @return bool
+     */
+    fun isDirectory(context: Context, path: String): Boolean {
+        val resolver = context.contentResolver
+        val columns = arrayOf(
+            DocumentsContract.Document.COLUMN_MIME_TYPE
+        )
+        var isDirectory = false
+        var c: Cursor? = null
+        try {
+            val mUri = Uri.parse(path)
+            c = resolver.query(mUri, columns, null, null, null)
+            c!!.moveToNext()
+            val mimeType = c.getString(0)
+            isDirectory = mimeType == DocumentsContract.Document.MIME_TYPE_DIR
+        } catch (e: Exception) {
+            Log.error("[FileUtil]: Cannot list files, error: " + e.message)
+        } finally {
+            closeQuietly(c)
+        }
+        return isDirectory
+    }
+
+    /**
+     * Get file display name from given path
+     * @param path content uri path
+     * @return String display name
+     */
+    fun getFilename(context: Context, path: String): String {
+        val resolver = context.contentResolver
+        val columns = arrayOf(
+            DocumentsContract.Document.COLUMN_DISPLAY_NAME
+        )
+        var filename = ""
+        var c: Cursor? = null
+        try {
+            val mUri = Uri.parse(path)
+            c = resolver.query(mUri, columns, null, null, null)
+            c!!.moveToNext()
+            filename = c.getString(0)
+        } catch (e: Exception) {
+            Log.error("[FileUtil]: Cannot get file size, error: " + e.message)
+        } finally {
+            closeQuietly(c)
+        }
+        return filename
+    }
+
+    fun getFilesName(context: Context, path: String): Array<String> {
+        val uri = Uri.parse(path)
+        val files: MutableList<String> = ArrayList()
+        for (file in listFiles(context, uri)) {
+            files.add(file.filename)
+        }
+        return files.toTypedArray()
+    }
+
+    /**
+     * Get file size from given path.
+     * @param path content uri path
+     * @return long file size
+     */
+    @JvmStatic
+    fun getFileSize(context: Context, path: String): Long {
+        val resolver = context.contentResolver
+        val columns = arrayOf(
+            DocumentsContract.Document.COLUMN_SIZE
+        )
+        var size: Long = 0
+        var c: Cursor? = null
+        try {
+            val mUri = Uri.parse(path)
+            c = resolver.query(mUri, columns, null, null, null)
+            c!!.moveToNext()
+            size = c.getLong(0)
+        } catch (e: Exception) {
+            Log.error("[FileUtil]: Cannot get file size, error: " + e.message)
+        } finally {
+            closeQuietly(c)
+        }
+        return size
+    }
+
+    @JvmStatic
+    fun copyUriToInternalStorage(
+        context: Context,
+        sourceUri: Uri?,
+        destinationParentPath: String,
+        destinationFilename: String
+    ): Boolean {
+        var input: InputStream? = null
+        var output: FileOutputStream? = null
+        try {
+            input = context.contentResolver.openInputStream(sourceUri!!)
+            output = FileOutputStream("$destinationParentPath/$destinationFilename")
+            val buffer = ByteArray(1024)
+            var len: Int
+            while (input!!.read(buffer).also { len = it } != -1) {
+                output.write(buffer, 0, len)
+            }
+            output.flush()
+            return true
+        } catch (e: Exception) {
+            Log.error("[FileUtil]: Cannot copy file, error: " + e.message)
+        } finally {
+            if (input != null) {
+                try {
+                    input.close()
+                } catch (e: IOException) {
+                    Log.error("[FileUtil]: Cannot close input file, error: " + e.message)
+                }
+            }
+            if (output != null) {
+                try {
+                    output.close()
+                } catch (e: IOException) {
+                    Log.error("[FileUtil]: Cannot close output file, error: " + e.message)
+                }
+            }
+        }
+        return false
+    }
+
+    fun isRootTreeUri(uri: Uri): Boolean {
+        val paths = uri.pathSegments
+        return paths.size == 2 && PATH_TREE == paths[0]
+    }
+
+    fun closeQuietly(closeable: AutoCloseable?) {
+        if (closeable != null) {
+            try {
+                closeable.close()
+            } catch (rethrown: RuntimeException) {
+                throw rethrown
+            } catch (ignored: Exception) {
+            }
+        }
+    }
+}