@@ -3,6 +3,8 @@ package com.reactnativedocumentpicker
3
3
import android.content.ContentResolver
4
4
import android.content.Context
5
5
import android.net.Uri
6
+ import android.os.Build
7
+ import android.os.FileUtils
6
8
import com.facebook.react.bridge.Arguments
7
9
import com.facebook.react.bridge.ReactApplicationContext
8
10
import com.facebook.react.bridge.ReactContext
@@ -18,7 +20,7 @@ import java.io.FileNotFoundException
18
20
import java.io.FileOutputStream
19
21
import java.io.IOException
20
22
import java.io.InputStream
21
- import java.nio.channels.Channels
23
+ import java.io.OutputStream
22
24
import java.util.UUID
23
25
24
26
class FileOperations (private val uriMap : MutableMap <String , Uri >) {
@@ -119,23 +121,17 @@ class FileOperations(private val uriMap: MutableMap<String, Uri>) {
119
121
val destFileSafe = safeGetDestination(attemptedDestFile, destinationDir)
120
122
121
123
val copyStreamToFile: (InputStream ? ) -> Unit = { inputStream ->
122
- if (inputStream == null ) {
123
- throw FileNotFoundException (" No input stream was found for the source file" )
124
- }
125
- FileOutputStream (destFileSafe).channel.use { destinationFileChannel ->
126
- val inputChannel = Channels .newChannel(inputStream)
127
- val size = destinationFileChannel.transferFrom(inputChannel, 0 , Long .MAX_VALUE )
128
- if (size == 0L ) {
129
- throw IOException (" No data was copied to the destination file" )
130
- }
124
+ inputStream ? : throw FileNotFoundException (" No input stream was found for the source file" )
125
+ val bytesCopied = copyStreamToAnother(inputStream, FileOutputStream (destFileSafe))
126
+ if (bytesCopied == 0L ) {
127
+ throw IOException (" No data was copied to the destination file" )
131
128
}
132
129
}
133
130
134
131
if (convertVirtualFileAsType == null ) {
135
- context.contentResolver.openInputStream(from).use(copyStreamToFile )
132
+ copyStreamToFile( context.contentResolver.openInputStream(from))
136
133
} else {
137
- getInputStreamForVirtualFile(context.contentResolver, from, convertVirtualFileAsType)
138
- .use(copyStreamToFile)
134
+ copyStreamToFile(getInputStreamForVirtualFile(context.contentResolver, from, convertVirtualFileAsType))
139
135
}
140
136
141
137
return destFileSafe
@@ -161,9 +157,7 @@ class FileOperations(private val uriMap: MutableMap<String, Uri>) {
161
157
}
162
158
163
159
fun writeDocumentImpl (sourceUri : Uri ? , targetUriString : String? , context : ReactApplicationContext ): DocumentMetadataBuilder {
164
- if (sourceUri == null ) {
165
- throw IllegalArgumentException (" The source URI is null. Call saveDocument() before writeDocument()" )
166
- }
160
+ sourceUri ? : throw IllegalArgumentException (" The source URI is null. Call saveDocument() before writeDocument()" )
167
161
val targetUri: Uri ? = uriMap[targetUriString]
168
162
169
163
if (targetUri == null ) {
@@ -180,25 +174,30 @@ class FileOperations(private val uriMap: MutableMap<String, Uri>) {
180
174
val mimeFromUri = contentResolver.getType(targetUri)
181
175
metadataBuilder.mimeType(mimeFromUri)
182
176
183
- // TODO https://gist.github.com/vonovak/73affb1a5b904ee165d9b5981d8dfe9a
184
- contentResolver.openInputStream(sourceUri).use { inputStream ->
185
- if (inputStream == null ) {
186
- metadataBuilder.metadataReadingError(" No output stream found for source file" )
187
- } else {
188
- contentResolver.openOutputStream(targetUri).use { outputStream ->
189
- if (outputStream == null ) {
190
- metadataBuilder.metadataReadingError(" No output stream found for destination file" )
191
- } else {
192
- val bytesCopied = inputStream.copyTo(outputStream)
193
- if (bytesCopied == 0L ) {
194
- metadataBuilder.metadataReadingError(" No data was copied to the destination file" )
195
- }
196
- outputStream.flush()
197
- }
198
- }
199
- }
177
+ val inputStream = contentResolver.openInputStream(sourceUri)
178
+ ? : return metadataBuilder.metadataReadingError(" No input stream found for source file" )
179
+
180
+ val outputStream = contentResolver.openOutputStream(targetUri)
181
+ ? : return metadataBuilder.metadataReadingError(" No output stream found for destination file" )
182
+
183
+ val bytesCopied = copyStreamToAnother(inputStream, outputStream)
184
+ if (bytesCopied == 0L ) {
185
+ metadataBuilder.metadataReadingError(" No data was copied to the destination file" )
200
186
}
201
187
202
188
return metadataBuilder
203
189
}
190
+
191
+ val copyStreamToAnother: (InputStream , OutputStream ) -> Long = { inputStream, outputStream ->
192
+ inputStream.use { input ->
193
+ outputStream.use { output ->
194
+ val bytesCopied = if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .Q ) {
195
+ FileUtils .copy(inputStream, outputStream)
196
+ } else {
197
+ inputStream.copyTo(outputStream)
198
+ }
199
+ return @use bytesCopied
200
+ }
201
+ }
202
+ }
204
203
}
0 commit comments