Олег Марков
Гайд по файловой системе в React Native
Введение
Файловая система — это ключевой компонент любого мобильного приложения, который позволяет работать с файлами: сохранять фотографии, хранить логи, создавать документы, кэшировать данные и даже организовывать офлайн-работу. В React Native работа с файлами слегка отличается от привычной работы в JavaScript в браузере или Node.js, поскольку на мобильных платформах (Android и iOS) действуют свои ограничения и особенности организации хранения данных.
В этой статье я подробно расскажу, как работать с файловой системой в React Native. На практических примерах вы узнаете, как записывать, читать, удалять файлы и директории, получать список файлов, вычислять хэш и многое другое. Здесь собрана вся основная информация, необходимая как начинающим, так и опытным мобильным разработчикам.
Обзор работы с файловой системой в React Native
По умолчанию React Native не предоставляет встроенных средств для работы с локальной файловой системой. Для этих целей наиболее популярен пакет react-native-fs
. Он кроссплатформенный и поддерживает все ключевые операции с файлами для Android и iOS.
Для определённых кейсов применяются также библиотеки expo-file-system
, rn-fetch-blob
, но в большинстве случаев современного приложения хватает возможностей react-native-fs
.
Работа с файловой системой в React Native позволяет сохранять и загружать данные, работать с изображениями и другими ресурсами. Важно понимать, как получить доступ к различным директориям, читать и записывать файлы, а также обрабатывать ошибки и обеспечивать безопасность данных. Для более глубокой работы с файлами может потребоваться понимание работы с нативными модулями. Если вы хотите детальнее погрузиться в работу с файловой системой и другими нативными возможностями в React Native, — приходите на наш большой курс React Native и Expo Router. На курсе 184 уроков и 11 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.
Установка и базовая настройка
Давайте начнем с установки:
npm install react-native-fs
# или
yarn add react-native-fs
После этого следуйте инструкции по установке Native-кода (особенно важно для старых версий React Native):
- Для Android убедитесь, что package автоматически линкован или пропишите его вручную в
android/settings.gradle
иandroid/app/build.gradle
(актуально для React Native до 0.60). - Для iOS выполните
cd ios && pod install
.
Теперь библиотека готова к работе, и вы можете импортировать её в своих файлах:
import RNFS from 'react-native-fs'
Основные директории и работа с путями
Перед тем, как приступить к чтению и записи, важно понять, где можно хранить файлы.
Основные стандартные директории
В мобильных ОС системой определено несколько папок для работы:
- DocumentDirectoryPath — директория для документов пользователя, разрешена синхронизация с iCloud.
- ExternalDirectoryPath (только Android) — внешний storage, видно пользователю.
- CachesDirectoryPath — папка для кэшированных данных, может быть очищена ОС.
- TemporaryDirectoryPath (iOS) — временные файлы.
Смотрите, как обратиться к этим папкам:
// Получаем путь к директории документов
const documentsPath = RNFS.DocumentDirectoryPath
// Путь к кэшу
const cachePath = RNFS.CachesDirectoryPath
// Для Android — внешний сторидж
const externalPath = RNFS.ExternalDirectoryPath
Полученные пути — обычные строки, их можно объединять с помощью /
или использовать специальные утилиты.
Пример построения пути к новому файлу
const myFilePath = `${RNFS.DocumentDirectoryPath}/myData.txt`
// Файл будет создан в директории документов
Чтение и запись файлов
Как записывать данные в файл
Запись данных предельно проста. Вот рабочий пример:
const filePath = `${RNFS.DocumentDirectoryPath}/hello.txt`
// Запишем строку Hello, world!
RNFS.writeFile(filePath, 'Hello, world!', 'utf8')
.then(() => {
// Запись прошла успешно
console.log('Файл создан!')
})
.catch(error => {
// При ошибке выводим ее в консоль
console.error('Ошибка записи файла:', error)
})
Вы всегда должны указывать кодировку — чаще всего используют utf8
.
Если файл уже существует, то функция перезапишет его полностью.
Чтение данных из файла
Прочитать данные можно так:
RNFS.readFile(filePath, 'utf8')
.then(contents => {
// В contents — строка из файла
console.log('Содержимое файла:', contents)
})
.catch(error => {
// Например, если файл не найден
console.error('Ошибка чтения файла:', error)
})
Если файл содержит бинарные данные — не забудьте поменять кодировку, например на base64
.
Работа с JSON
Очень удобно хранить сериализованные данные:
// Сохраним объект
const data = { loggedIn: true, name: 'Anna' }
await RNFS.writeFile(filePath, JSON.stringify(data), 'utf8')
// И потом прочитаем
const json = await RNFS.readFile(filePath, 'utf8')
const parsed = JSON.parse(json)
// parsed: { loggedIn: true, name: 'Anna' }
Используйте try-catch для ловли ошибок парсинга.
Работа с директориями
Проверка существования файлов и папок
Чтобы проверить, существует ли определённый файл или папка, используйте метод exists
:
const fileExists = await RNFS.exists(filePath)
if (fileExists) {
console.log('Файл есть')
} else {
console.log('Файла нет')
}
Создание и удаление директорий
Создать новую папку можно так:
await RNFS.mkdir(`${RNFS.DocumentDirectoryPath}/myFolder`)
Удалить папку (вместе с содержимым!) или файл — с помощью unlink
:
await RNFS.unlink(`${RNFS.DocumentDirectoryPath}/myFolder`)
// Будьте внимательны — папка удалится вместе со всеми файлами
Получение списка файлов в папке
Для просмотра содержимого директории:
const items = await RNFS.readDir(RNFS.DocumentDirectoryPath)
items.forEach(item => {
// Выводим путь к каждому элементу
console.log(item.path)
// item.isFile(), item.isDirectory() — позволяют узнать тип
})
Работа с бинарными файлами (картинки, аудио и проч.)
Многим разработчикам нужно сохранять не только текстовые данные, но и, например, фотографии пользователя или аудиозаписи.
Запись и чтение файлов в base64
Вам поможет работа с кодировкой base64
. Смотрите пример:
// Пример сохранения картинки в base64
await RNFS.writeFile(filePath, base64String, 'base64')
// Чтение картинки
const data = await RNFS.readFile(filePath, 'base64')
// Получили строку base64 для дальнейшего использования
Копирование и перемещение файлов
Иногда нужно скопировать или переместить файл из одной директории в другую. Для этого есть методы copyFile
и moveFile
.
// Копирование файла
await RNFS.copyFile(srcPath, destPath)
// Перемещение файла
await RNFS.moveFile(oldPath, newPath)
Оба метода не создают новые папки, если они отсутствуют — их нужно создать заранее!
Загрузка файлов из интернета
Для загрузки файлов используйте метод downloadFile
. Вот рабочий пример:
const destPath = `${RNFS.DocumentDirectoryPath}/image.jpg`
const options = {
fromUrl: 'https://example.com/image.jpg', // cсылка на файл
toFile: destPath, // куда сохранять
background: true, // выполнять в фоне
progress: res => {
const percent = (res.bytesWritten / res.contentLength) * 100
console.log(`Загрузка: ${percent}%`)
}
}
const download = RNFS.downloadFile(options)
const result = await download.promise
if (result.statusCode === 200) {
console.log('Файл загружен!')
}
В случае ошибок promise
завершится с ошибкой, которую нужно обработать через try-catch.
Особенности работы на Android и iOS
Пермишены и доступ к файлам
Android
С Android 6.0 и выше критически важно запрашивать разрешение на доступ к файловой системе у пользователя. Для этого используйте пакет @react-native-community/permissions
:
import { PermissionsAndroid } from 'react-native'
async function requestStoragePermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('Доступ есть')
} else {
console.log('Доступ запрещен')
}
} catch (err) {
console.warn(err)
}
}
Чтобы работать во "внешней" директории (ExternalDirectoryPath
), обязательно запрашивайте разрешения и пропишите их в AndroidManifest.xml
.
iOS
На iOS приложение всегда работает только в своем "песочнице", и доступ к файловой системе за её пределами получить нельзя. То есть файл, созданный приложением — доступен только ему.
Ограничения и тонкости платформ
- Android: В новых версиях (Android 11+) ужесточились правила доступа к файлам — используйте специально предназначенные директории (например,
DocumentDirectoryPath
). - iOS: Не используйте для хранения пользовательских данных временные каталоги (
TemporaryDirectoryPath
), т.к. iOS их может удалить в любой момент.
Прочие полезные методы
Получение информации о файле
Вы можете узнать размер, дату или другие сведения:
const stat = await RNFS.stat(filePath)
console.log(stat.size) // Размер файла в байтах
console.log(stat.mtime) // Дата последней модификации
console.log(stat.isFile()) // true если файл, false если папка
console.log(stat.isDirectory())
Вычисление хэша файла
Если требуется уникально идентифицировать файл или сравнить его содержимое:
const hash = await RNFS.hash(filePath, 'md5')
console.log(`MD5 хэш файла: ${hash}`)
Пример: сохранение и отображение картинки
Давайте рассмотрим распространённый кейс — пользователь выбирает фото, оно сохраняется в файловой системе и затем отображается в приложении.
Пояснения будут даны пошагово
- Сохраняем base64-строку как файл:
const filePath = `${RNFS.DocumentDirectoryPath}/myImage.jpg`
await RNFS.writeFile(filePath, base64String, 'base64')
- Открываем файл через компонент Image:
import { Image } from 'react-native'
<Image
source={{ uri: `file://${filePath}` }} // file:// обязателен!
style={{ width: 100, height: 100 }}
/>
file://
— важная часть пути, иначе изображение может не загрузиться!
- Для удаления фото используйте:
await RNFS.unlink(filePath)
Безопасность и большие файлы
Обработка больших файлов требует осторожности — не читайте их в оперативную память целиком, используйте методы потоковой работы (read()
с указанием количества байт, если критично). Всегда валидируйте пользовательские данные перед сохранением.
Храните sensitive-данные только в директории приложения, защищённой ОС, и не отдавайте доступ сторонним приложениям.
Заключение
Работа с файловой системой в React Native становится максимально удобной при использовании проверенных библиотек, таких как react-native-fs
. С их помощью вы сможете реализовать все основные сценарии по хранению, чтению, удалению и загрузке файлов. В статье были разобраны ключевые методы, особенности работы с директориями, текстовыми и бинарными файлами, вопросы безопасности и платформенные нюансы.
Вы можете смело использовать эти знания для создания офлайн-режимов в приложении, работы с фото/видео, кэширования данных, хранения конфиденциальной информации и интеграции с сервисами на устройствах пользователей.
Работа с файловой системой - это важный аспект разработки, но не стоит забывать и о других важных вещах, как управление состоянием и создание навигации. На нашем курсе React Native и Expo Router вы найдете все необходимые знания для освоения React Native разработки. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в мир React Native прямо сегодня.
Частозадаваемые технические вопросы
Как очистить все файлы из определённой папки?
— Получите список файлов через readDir
, затем для каждого файла вызовите unlink
. Пример:
javascript
const files = await RNFS.readDir(folderPath)
for (const file of files) {
await RNFS.unlink(file.path)
}
Почему файлы пропадают после обновления приложения (Android)?
— Если файлы хранились во временных или кэширующих директориях, система могла их очистить. Используйте DocumentDirectoryPath
или ExternalDirectoryPath
для долгосрочного хранения.
Как ограничить размер кэшируемых файлов?
— После каждой записи файла проверяйте общий размер через сумму свойств size
всех файлов в директории. Если превышаете лимит, удаляйте самые старые с помощью сортировки по mtime
.
Как работать с файлами PDF?
— Для работы с PDF-файлами используйте те же методы для сохранения и чтения, а для отображения используйте компоненты типа react-native-pdf
, передавая в source
путь к файлу ({ uri: 'file://' + filePath }
).
Как защитить файлы от чтения другими приложениями?
— На Android храните важные файлы во внутренней директории приложения (DocumentDirectoryPath
). На iOS все файлы по умолчанию доступны только вашему приложению благодаря "песочнице".
Постройте личный план изучения React-native до уровня Middle — бесплатно!
React-native — часть карты развития Mobile
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по React-native
Лучшие курсы по теме

React Native и Expo Router
Антон Ларичев
Основы JavaScript
Антон Ларичев