react-native-file-access
Filesystem access for React Native. Supports saving network requests directly
to the filesystem. Supports Android scoped storage, a requirement when targeting
API 30 or higher.
Installation
npm install react-native-file-access
cd ios && pod install
If the app does not use autolinking, continue to the manual install instructions in the wiki.
Compatibility
For React Native 0.64 and older, use 1.x.x. For React Native 0.65+, use 2.x.x.
Usage
import { Dirs, FileSystem } from 'react-native-file-access';
const text = await FileSystem.readFile(Dirs.CacheDir + '/test.txt');
Directory constants.
Dirs.CacheDir
Dirs.DatabaseDir
(Android only)Dirs.DocumentDir
Dirs.LibraryDir
(iOS & MacOS only)Dirs.MainBundleDir
Dirs.SDCardDir
(Android only)
- Prefer
FileSystem.cpExternal()
when possible.
Functions.
FileSystem.appendFile(path: string, data: string, encoding?: 'utf8' | 'base64'): Promise<void>
- Append content to a file.
- Default encoding of
data
is assumed utf8.
FileSystem.concatFiles(source: string, target: string): Promise<number>
- Append a file to another file. Returns number of bytes written.
FileSystem.cp(source: string, target: string): Promise<void>
FileSystem.cpAsset(asset: string, target: string, type?: 'asset' | 'resource'): Promise<void>
- Copy a bundled asset file.
- Default
type
is asset
. Prefer this when possible. resource
uses the Android res/
folder, and inherits the associated
naming restrictions.
FileSystem.cpExternal(source: string, targetName: string, dir: 'audio' | 'downloads' | 'images' | 'video'): Promise<void>
- Copy a file to an externally controlled location.
- On Android API level < 29, may require permission WRITE_EXTERNAL_STORAGE.
- On iOS, consider using
Dirs.DocumentDir
with UIFileSharingEnabled
and LSSupportsOpeningDocumentsInPlace
enabled.
FileSystem.df(): Promise<{ internal_free: number, internal_total: number, external_free?: number, external_total?: number }>
- Check device available space.
FileSystem.exists(path: string): Promise<boolean>
FilesSystem.fetch(
resource: string,
init: { body?: string, headers?: { [key: string]: string }, method?: string, network?: 'any' | 'unmetered', path?: string },
onProgress?: (bytesRead: number, contentLength: number, done: boolean) => void
): Promise<FetchResult>
type FetchResult = {
headers: { [key: string]: string };
ok: boolean;
redirected: boolean;
status: number;
statusText: string;
url: string;
}
- Save a network request to a file.
resource
- URL to fetch.init.path
- Optional filesystem location to save the response.init.network
- Optional restriction on network type. Specifying
unmetered
will reject the request if unmetered connections (most likely
WiFi) are unavailable.onProgress
- Optional callback to listen to download progress. Events
are rate limited, so do not rely on done
becoming true
.
contentLength
is only accurate if the server sends the correct headers.
FilesSystem.fetchManaged(
resource: string,
init: { body?: string, headers?: { [key: string]: string }, method?: string, network?: 'any' | 'unmetered', path?: string },
onProgress?: (bytesRead: number, contentLength: number, done: boolean) => void
): ManagedFetchResult
type ManagedFetchResult = {
cancel: () => Promise<void>;
result: Promise<FetchResult>;
}
- Save a network request to a file.
- Similar to
fetch()
, with the option to cancel before completion.
FilesSystem.getAppGroupDir(groupName: string): Promise<string>
- Get the directory for your app group (iOS & MacOS only).
- App groups are used on iOS/MacOS for storing content, which is shared between apps.
- This is e.g. useful for sharing data between your iOS/MacOS app and a widget or a watch app.
FilesSystem.hash(path: string, algorithm: 'MD5' | 'SHA-1' | 'SHA-224' | 'SHA-256' | 'SHA-384' | 'SHA-512'): Promise<string>
FilesSystem.isDir(path: string): Promise<boolean>
- Check if a path is a directory.
FileSystem.ls(path: string): Promise<string[]>
- List files in a directory.
FileSystem.mkdir(path: string): Promise<string>
- Make a new directory.
- Returns path of created directory.
FileSystem.mv(source: string, target: string): Promise<void>
FileSystem.readFile(path: string, encoding?: 'utf8' | 'base64'): Promise<string>
- Read the content of a file.
- Default encoding of returned string is utf8.
FileSystem.stat(path: string): Promise<FileStat>
type FileStat = {
filename: string;
lastModified: number;
path: string;
size: number;
type: 'directory' | 'file';
}
FileSystem.statDir(path: string): Promise<FileStat[]>
- Read metadata of all files in a directory.
FileSystem.unlink(path: string): Promise<void>
FileSystem.unzip(source: string, target: string): Promise<void>
FileSystem.writeFile(path: string, data: string, encoding?: 'utf8' | 'base64'): Promise<void>
- Write content to a file.
- Default encoding of
data
is assumed utf8.
Utility functions.
Util.basename(path: string, separator?: string): string
- Get the file/folder name from the end of the path.
- Default path
separator
is /
.
Util.dirname(path: string, separator?: string): string
- Get the path containing the file/folder.
- Default path
separator
is /
.
Util.extname(path: string, separator?: string): string
- Get the file extension.
- Default path
separator
is /
.
Scoped storage.
For simple usage, use FileSystem.cpExternal()
to submit files to general
scoped storage categories.
Most functions in this library work with content://
Android resource uris.
To gain access to a resource uri, currently use a library such as
react-native-document-picker or
react-native-scoped-storage.
Eventually this library will incorporate file/folder selector functionality
(pull requests welcome).
Note:
- When generating a scoped storage resource uri, use the helper
AndroidScoped.appendPath(dir, 'data.txt')
, not dir + '/data.txt'
. - Android may change the name of created files/folders.
AndroidScoped.appendPath(basePath: string, segment: string): string
- Append a path segment to an Android scoped storage content uri.
Testing
For ease of testing, this library contains a mock implementation:
jest/react-native-file-access.ts.
To use, copy it into the __mocks__
folder, modifying if needed.
Alternatives
This library aims to be a modern implementation of filesystem api, using Kotlin/Swift
and latest best practices. For a more established library, consider:
For more greater control over network requests, consider
react-native-blob-courier.
Contributing
See the contributing guide to learn how to contribute to the repository and the development workflow.
License
MIT