1
1
package com.alpha0010.fs
2
2
3
3
import android.content.ContentValues
4
+ import android.net.Uri
4
5
import android.os.Environment
5
6
import android.os.StatFs
6
7
import android.provider.MediaStore
@@ -15,6 +16,7 @@ import okhttp3.Callback
15
16
import java.io.File
16
17
import java.io.FileOutputStream
17
18
import java.io.IOException
19
+ import java.io.InputStream
18
20
import java.security.MessageDigest
19
21
20
22
class FileAccessModule (reactContext : ReactApplicationContext ) : ReactContextBaseJavaModule(reactContext) {
@@ -61,7 +63,7 @@ class FileAccessModule(reactContext: ReactApplicationContext) : ReactContextBase
61
63
@ReactMethod
62
64
fun concatFiles (source : String , target : String , promise : Promise ) {
63
65
try {
64
- File (source).inputStream( ).use { input ->
66
+ openForReading (source).use { input ->
65
67
FileOutputStream (File (target), true ).use {
66
68
promise.resolve(input.copyTo(it).toInt())
67
69
}
@@ -75,7 +77,9 @@ class FileAccessModule(reactContext: ReactApplicationContext) : ReactContextBase
75
77
fun cp (source : String , target : String , promise : Promise ) {
76
78
ioScope.launch {
77
79
try {
78
- File (source).copyTo(File (target), overwrite = true )
80
+ openForReading(source).use { input ->
81
+ File (target).outputStream().use { input.copyTo(it) }
82
+ }
79
83
promise.resolve(null )
80
84
} catch (e: Throwable ) {
81
85
promise.reject(e)
@@ -98,7 +102,7 @@ class FileAccessModule(reactContext: ReactApplicationContext) : ReactContextBase
98
102
@ReactMethod
99
103
fun cpExternal (source : String , targetName : String , dir : String , promise : Promise ) {
100
104
try {
101
- File (source).inputStream( ).use { input ->
105
+ openForReading (source).use { input ->
102
106
if (dir == " downloads" ) {
103
107
if (android.os.Build .VERSION .SDK_INT >= android.os.Build .VERSION_CODES .Q ) {
104
108
reactApplicationContext.contentResolver.insert(
@@ -254,7 +258,7 @@ class FileAccessModule(reactContext: ReactApplicationContext) : ReactContextBase
254
258
fun hash (path : String , algorithm : String , promise : Promise ) {
255
259
try {
256
260
val digest = MessageDigest .getInstance(algorithm)
257
- File (path).inputStream( ).use {
261
+ openForReading (path).use {
258
262
val buffer = ByteArray (DEFAULT_BUFFER_SIZE )
259
263
var bytes = it.read(buffer)
260
264
while (bytes >= 0 ) {
@@ -333,10 +337,11 @@ class FileAccessModule(reactContext: ReactApplicationContext) : ReactContextBase
333
337
@ReactMethod
334
338
fun readFile (path : String , encoding : String , promise : Promise ) {
335
339
try {
340
+ val data = openForReading(path).use { it.readBytes() }
336
341
if (encoding == " base64" ) {
337
- promise.resolve(Base64 .encodeToString(File (path).readBytes() , Base64 .DEFAULT ))
342
+ promise.resolve(Base64 .encodeToString(data , Base64 .DEFAULT ))
338
343
} else {
339
- promise.resolve(File (path).readText ())
344
+ promise.resolve(data.decodeToString ())
340
345
}
341
346
} catch (e: Throwable ) {
342
347
promise.reject(e)
@@ -391,4 +396,16 @@ class FileAccessModule(reactContext: ReactApplicationContext) : ReactContextBase
391
396
}
392
397
}
393
398
}
399
+
400
+ /* *
401
+ * Open a file. Supports both standard file system paths and Storage Access
402
+ * Framework content URIs.
403
+ */
404
+ private fun openForReading (path : String ): InputStream {
405
+ return if (path.startsWith(" content://" )) {
406
+ reactApplicationContext.contentResolver.openInputStream(Uri .parse(path))!!
407
+ } else {
408
+ File (path).inputStream()
409
+ }
410
+ }
394
411
}
0 commit comments