Crash when readStream on IOS
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
I have the same error. @tsogzark, did you fix it?
I have the same error. @tsogzark, did you fix it?
I split the file into smaller chunks for transmission.
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
)}`
);