Before you start
Make sure the new React Native architecture is enabled. In expo
, which I’m using for this example, you can set "newArchEnabled": true
in your app.json.
expo-file-system/next
is the next-gen version of expo-file-system
. It’s included in the latest versions to use. Using this and the new “Bridge-less” architecture, led to some massive performance increases in one of my apps where I load (multi-megabyte) files that are stored in the app’s document directory.
Example Code
import { Buffer } from 'buffer' // https://www.npmjs.com/package/buffer
import { File } from 'expo-file-system/next'
// construct a file
const fileObj = new File(filePath) // filePath is a file:/// url to the file on-disk.
// open a FileHandle
const fh = fileObj.open()
const bytes = fh.readBytes(fh.size) // reads entire file into a Uint8Array
// turn the bytes into a buffer
const buffer = Buffer.from(bytes)
Read at an offset
The FileHandler has an offset
property. This enables you to do random access reads within a file without reading the entire thing into memory.
const fh = fileObj.open()
fh.offset = 512 // offset to 512 bytes
const bytes = fh.readBytes(512) // read 2nd 512 bytes from the file.
What this replaces
The older version of this, requires you to load as a base64 string and send it over the React Native bridge. That was not efficient, and comparatively very slow. In one of my apps, replacing this with the new version above reduced the load time from ~5 seconds to less than 1 second.
import * as FileSystem from 'expo-file-system';
// The SLOW, older version:
const data = await FileSystem.readAsStringAsync(fileUri, { encoding: 'base64' })
const buffer = Buffer.Buffer.from(data, 'base64')