@@ -3,6 +3,8 @@ package com.reactnativedocumentpicker
33import android.content.ContentResolver
44import android.content.Context
55import android.net.Uri
6+ import android.os.Build
7+ import android.os.FileUtils
68import com.facebook.react.bridge.Arguments
79import com.facebook.react.bridge.ReactApplicationContext
810import com.facebook.react.bridge.ReactContext
@@ -18,7 +20,7 @@ import java.io.FileNotFoundException
1820import java.io.FileOutputStream
1921import java.io.IOException
2022import java.io.InputStream
21- import java.nio.channels.Channels
23+ import java.io.OutputStream
2224import java.util.UUID
2325
2426class FileOperations (private val uriMap : MutableMap <String , Uri >) {
@@ -119,23 +121,17 @@ class FileOperations(private val uriMap: MutableMap<String, Uri>) {
119121 val destFileSafe = safeGetDestination(attemptedDestFile, destinationDir)
120122
121123 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" )
131128 }
132129 }
133130
134131 if (convertVirtualFileAsType == null ) {
135- context.contentResolver.openInputStream(from).use(copyStreamToFile )
132+ copyStreamToFile( context.contentResolver.openInputStream(from))
136133 } else {
137- getInputStreamForVirtualFile(context.contentResolver, from, convertVirtualFileAsType)
138- .use(copyStreamToFile)
134+ copyStreamToFile(getInputStreamForVirtualFile(context.contentResolver, from, convertVirtualFileAsType))
139135 }
140136
141137 return destFileSafe
@@ -161,9 +157,7 @@ class FileOperations(private val uriMap: MutableMap<String, Uri>) {
161157 }
162158
163159 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()" )
167161 val targetUri: Uri ? = uriMap[targetUriString]
168162
169163 if (targetUri == null ) {
@@ -180,25 +174,30 @@ class FileOperations(private val uriMap: MutableMap<String, Uri>) {
180174 val mimeFromUri = contentResolver.getType(targetUri)
181175 metadataBuilder.mimeType(mimeFromUri)
182176
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" )
200186 }
201187
202188 return metadataBuilder
203189 }
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+ }
204203}
0 commit comments