expo-file-system
Rutas de espacio aislado, descargas y migración desde la API de FS heredada - el manual de expo-file-system para aplicaciones Expo SDK 57 que almacenan en caché PDFs, fotos y payloads sin conexión en el dispositivo.
Busca en todas las páginas de la documentación
Rutas de espacio aislado, descargas y migración desde la API de FS heredada - el manual de expo-file-system para aplicaciones Expo SDK 57 que almacenan en caché PDFs, fotos y payloads sin conexión en el dispositivo.
Tarjeta de referencia rápida - lista para copiar y pegar.
npx expo install expo-file-systemimport { Directory, File, Paths } from "expo-file-system";
export function ensureDownloadDir() {
const dir = new Directory(Paths.cache, "downloads");
if (!dir.exists) {
dir.create();
}
return dir;
}
export async function downloadPdf(url: string, filename: string) {
const dir = ensureDownloadDir();
const output = await File.downloadFileAsync(url, dir);
return output.uri;
}
export function writeJsonCache(name: string, data: unknown) {
const file = new File(Paths.cache, `${name}.json`);
if (!file.exists) {
file.create();
}
file.write(JSON.stringify(data));
}Cuándo usarlo:
File.createUploadTask.Cuándo evitarlo:
Descarga con progreso, metadatos JSON lateral e interoperabilidad heredada durante la migración.
npx expo install expo-file-system// src/files/downloadWithProgress.ts
import { Directory, File, Paths } from "expo-file-system";
export async function downloadInspectionPdf(
url: string,
jobId: string,
onProgress: (ratio: number) => void
) {
const dir = new Directory(Paths.document, "inspections", jobId);
if (!dir.exists) {
dir.create({ intermediates: true });
}
const destination = new File(dir, "report.pdf");
const task = File.createDownloadTask(url, destination, {
onProgress: ({ bytesWritten, totalBytes }) => {
if (totalBytes > 0) {
onProgress(bytesWritten / totalBytes);
}
},
});
const file = await task.downloadAsync();
if (!file) throw new Error("Download paused or cancelled");
const meta = new File(dir, "meta.json");
meta.create();
meta.write(JSON.stringify({ url, downloadedAt: Date.now() }));
return file.uri;
}// src/files/listInspections.ts
import { Directory, Paths } from "expo-file-system";
export function listInspectionJobIds(): string[] {
const root = new Directory(Paths.document, "inspections");
if (!root.exists) return [];
return root
.list()
.filter((entry) => entry instanceof Directory)
.map((d) => d.name);
}// src/files/legacyRead.ts - puente temporal
import * as FileSystem from "expo-file-system/legacy";
import { File, Paths } from "expo-file-system";
export async function readLegacyManifest() {
const file = new File(Paths.cache, "legacy-manifest.json");
if (!file.exists) return null;
const text = await FileSystem.readAsStringAsync(file.uri);
return JSON.parse(text) as { version: number };
}Lo que esto demuestra:
Paths.document para PDFs significativos para el usuario - sobrevive a barridos de caché.createDownloadTask con devolución de llamada de progreso para barras de UI.Directory.list() para enumerar carpetas de trabajo.| Ruta | Persistencia | Uso típico |
|---|---|---|
Paths.document | Hasta que se desinstale la aplicación | Exportaciones del usuario, PDFs de inspección |
Paths.cache | El SO puede eliminar | Miniaturas, descargas temporales |
Paths.bundle | Activos empaquetados de solo lectura | Archivos de inicialización en el primer lanzamiento |
import { Paths } from "expo-file-system";
console.log(Paths.document.uri);
console.log(Paths.cache.uri);file.exists.const dir = new Directory(Paths.cache, "avatars");
dir.create({ intermediates: true });
const avatar = dir.createFile("user-42.jpg", "image/jpeg");
avatar.write(bytes);
const copy = new File(Paths.cache, "avatars", "user-42-copy.jpg");
avatar.copy(copy);
avatar.move(new Directory(Paths.document, "archive"));file://.exists antes de leer - los lanzamientos son para tipo File/Directory incorrecto en rutas existentes.textSync / bytesSync para archivos pequeños - variantes asincrónicas para payloads grandes.// Descarga simple de una sola vez
await File.downloadFileAsync(url, new Directory(Paths.cache, "pdfs"));
// Carga con progreso
const file = new File(Paths.document, "photo.jpg");
const task = file.createUploadTask("https://api.example.com/upload", {
uploadType: File.UploadType?.MULTIPART ?? 1,
onProgress: ({ bytesSent, totalBytes }) => {
console.log(bytesSent, totalBytes);
},
});
await task.uploadAsync();expo/fetch con cuerpo File para multipart cuando las opciones de tarea de carga son excesivas.// Antes (heredado)
import * as FileSystem from "expo-file-system/legacy";
await FileSystem.readAsStringAsync(uri);
// Después (SDK 57)
import { File } from "expo-file-system";
const file = new File(uri);
const text = file.textSync();expo-file-system/legacy solo en sitios de llamada no migrados.File a partir de cadenas URI heredadas - new File(existingUri).npx expo doctor y grep muestren cero importaciones /legacy.{
"expo": {
"plugins": [
[
"expo-file-system",
{
"enableFileSharing": true,
"supportsOpeningDocumentsInPlace": true
}
]
]
}
}documentDirectory - útil para PDFs exportados.Paths.document.new File(Paths.cache, "a", "b.txt").bytes() / flujos.intermediates: true - Falla de create() anidado. Solución: { intermediates: true } en rutas profundas.| Alternativa | Usa cuando | No uses cuando |
|---|---|---|
File / Directory API | Código nuevo de SDK 57 | Mantener aplicaciones SDK 54 sin ancho de banda de migración |
expo-file-system/legacy | Módulos no migrados | Características nuevas |
expo-sqlite | Filas relacionales | Blobs binarios grandes |
AsyncStorage | Prefs JSON pequeñas | Archivos más grandes que unos pocos KB |
npx expo install expo-file-systemImporta { File, Directory, Paths } desde expo-file-system - no solo el espacio de nombres predeterminado.
Paths.cache en actualización de versión de aplicación o acción de configuración.import { File, Paths } from "expo-file-system";
const seed = new File(Paths.bundle, "seed-data.json");const dir = new Directory(Paths.document, "inspections", jobId);
if (dir.exists) dir.delete(); // recursivoVersiones de stack: Esta página fue escrita para React 19.2.3, React Native 0.86.0 y Expo SDK 57 (
expo~57.0.4).
Revisado por Chris St. John·Última actualización: 16 jul 2026