react-native-blob-util icon indicating copy to clipboard operation
react-native-blob-util copied to clipboard

Crash when readStream on IOS

Open tsogzark opened this issue 1 year ago • 2 comments

Reproduce

I met the issue when i use this function to read a 300MB file on ios and when I read a 3MB it works well. It works well on android when read 300MB file, too.

   public splitLargeFile = async (localPath: string) => {
        let chunkCount = 0;
        const basename = localPath.split('/').pop();
        const bufferSize = 1024 * 900;
        RNFetchBlob.fs.readStream(
            localPath,
            'base64',
            bufferSize
        )
        .then((ifstream) => {
            ifstream.open();
            ifstream.onData(chunk => {
                chunkCount += 1;
                console.log(`${basename} chunk ${chunkCount*bufferSize}`);
            });
           ifstream.onError(err => {
                console.log('oops', err)
            });
            ifstream.onEnd(() => {
                console.log("End")
            });
        })
    }

Error

 LOG  2afae907f0696430905e416aca57f2ce.MP4 chunk 157593600
 LOG  2afae907f0696430905e416aca57f2ce.MP4 chunk 158515200
 LOG  oops [Error: Failed to convert data to 'base64' encoded string, this might due to the source data is not able to convert using this encoding. source = Failed to grow buffer]
 WARN  Failed to convert data to 'base64' encoded string, this might due to the source data is not able to convert using this encoding. source = Failed to grow buffer
 WARN  Failed to convert data to 'base64' encoded string, this might due to the source data is not able to convert using this encoding. source = Failed to grow buffer

log source

https://github.com/RonRadtke/react-native-blob-util/blob/618685faafaef005e3aabbf13933ee2767f9f2b5/ios/ReactNativeBlobUtilFS.mm#L271

tsogzark avatar May 03 '24 14:05 tsogzark

I have the same error. @tsogzark, did you fix it?

ivaniuk7531 avatar Oct 07 '24 20:10 ivaniuk7531

I have the same error. @tsogzark, did you fix it?

I split the file into smaller chunks for transmission.

tsogzark avatar Oct 12 '24 14:10 tsogzark

It might be a memory crash when the app starts reading too much into memory. Based on the docs, replace fs.readStream by fs.slice(path_to_source path_to_write, firstByte, lastByte). Code example below:

const startTime = Date.now();

       const path = isIOS() ? file.uri.replace('file://', '') : file.uri;

       let firstByte = 0;

       // Process file in chunks
       while (firstByte < fileSize) {
         const lastByte = Math.min(
           firstByte + DEFAULT_CHUNK_SIZE_UPLOAD,
           fileSize
         );
         const chunkPath = `${ReactNativeBlobUtil.fs.dirs.CacheDir}_${file.name}-${firstByte}-${lastByte}.tmp`;

         // Slice the file
         await ReactNativeBlobUtil.fs.slice(
           decodeURIComponent(path),
           decodeURIComponent(chunkPath),
           firstByte,
           lastByte
         );

         // Process the chunk (e.g., upload, read, or further process)
         // Example: Read chunk for further processing (optional)
         const chunkData = await ReactNativeBlobUtil.fs.readFile(
           chunkPath,
           'base64'
         );
         // Do something with chunkData (e.g., upload)
         Logger.info(`chunkPath created: ${chunkPath}`);

         // Clean up temporary chunk file
         await ReactNativeBlobUtil.fs.unlink(chunkPath);

         // Move to next chunk
         firstByte += DEFAULT_CHUNK_SIZE_UPLOAD;
       }

       const totalDuration = Date.now() - startTime;
       Logger.warn(
         `Total processing time: ${totalDuration}ms for ${formatFileSize(
           fileSize
         )}`
       );

dbs-tuan avatar May 20 '25 02:05 dbs-tuan