android: Convert FileUtil to Kotlin
This commit is contained in:
		| @@ -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) { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -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) { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user