Trabajando con Archivos Usando la API FileReader
Cuando un usuario selecciona un archivo en tu aplicación web, obtienes un objeto File — pero ¿cómo lees realmente su contenido? Ahí es donde entra la API FileReader de JavaScript. Este artículo explica cómo funciona FileReader, cuándo usarla y cómo se compara con las alternativas modernas.
Puntos Clave
- La API FileReader lee el contenido de objetos
FileoBlobde forma asíncrona usando uno de tres métodos:readAsText(),readAsArrayBuffer()oreadAsDataURL(). - FileReader utiliza un modelo basado en eventos con
load,error,progressy otros eventos para comunicar resultados. - Puedes envolver FileReader en una Promise para una integración más limpia con código
async/await. - Los métodos modernos
Blob.text()yBlob.arrayBuffer()son más simples para lecturas básicas, pero FileReader sigue siendo la opción correcta cuando necesitas seguimiento de progreso, codificación no UTF-8 o URLs de datos en base64.
¿Qué es la API FileReader?
La API FileReader es una interfaz del navegador que lee el contenido de objetos File o Blob de forma asíncrona. No puede acceder a archivos arbitrarios en el sistema del usuario mediante rutas — solo funciona con archivos que el usuario ha seleccionado explícitamente, ya sea a través de <input type="file"> o una interacción de arrastrar y soltar.
const input = document.querySelector('input[type="file"]')
input.addEventListener('change', () => {
const file = input.files[0]
console.log(file.name, file.size, file.type)
})
Un objeto File hereda de Blob, por lo que tiene las mismas propiedades más name y lastModified. Lo pasas directamente a cualquier método de lectura de FileReader.
Los Tres Métodos de Lectura Principales
Leer archivos locales en JavaScript con FileReader significa elegir el formato de salida correcto:
readAsText(file, encoding?)— Devuelve el contenido del archivo como una cadena de texto. Por defecto usa UTF-8. Útil para CSV, JSON, texto plano o cualquier formato basado en texto.readAsArrayBuffer(file)— Devuelve datos binarios sin procesar como unArrayBuffer. Úsalo para imágenes, audio, PDFs o cualquier procesamiento binario.readAsDataURL(file)— Devuelve una URLdata:codificada en base64. Conveniente para vistas previas de imágenes, pero ten en cuenta que el resultado es aproximadamente un 33% más grande que el archivo original debido a la sobrecarga de codificación base64.
Evita
readAsBinaryString()— está obsoleto. UsareadAsArrayBuffer()en su lugar para datos binarios.
El Modelo Basado en Eventos de FileReader
FileReader es asíncrono y se comunica a través de eventos. Los principales son:
| Evento | Cuándo se dispara |
|---|---|
loadstart | Comienza la lectura |
progress | Se dispara periódicamente durante la lectura |
load | Lectura completada exitosamente |
error | La lectura falló |
loadend | Lectura finalizada (éxito o fallo) |
Aquí hay un ejemplo práctico de vista previa de imagen antes de subir usando readAsDataURL():
function previewImage(file) {
const reader = new FileReader()
reader.addEventListener('load', () => {
const img = document.querySelector('#preview')
img.src = reader.result
})
reader.addEventListener('error', () => {
console.error('Failed to read file:', reader.error)
})
reader.readAsDataURL(file)
}
El evento progress es particularmente útil para mostrar una barra de progreso con archivos grandes:
reader.addEventListener('progress', (event) => {
if (event.lengthComputable) {
const percent = Math.round((event.loaded / event.total) * 100)
progressBar.value = percent
}
})
Discover how at OpenReplay.com.
Envolviendo FileReader en una Promise
El estilo de callbacks de FileReader puede resultar incómodo en código asíncrono moderno. Un wrapper simple soluciona esto:
function readFileAsText(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.addEventListener('load', () => resolve(reader.result))
reader.addEventListener('error', () => reject(reader.error))
reader.readAsText(file)
})
}
// Uso
const text = await readFileAsText(file)
FileReader vs Blob.text() y Blob.arrayBuffer()
Los navegadores modernos soportan métodos basados en promesas directamente en Blob (y por lo tanto en File):
// Enfoque moderno — más simple para lecturas básicas
const text = await file.text()
const buffer = await file.arrayBuffer()
Entonces, ¿cuándo deberías seguir usando FileReader? Elige FileReader cuando necesites:
- Seguimiento de progreso a través del evento
progress(aunque para archivos locales algunos navegadores pueden disparar solo un pequeño número de eventos de progreso) - Soporte de codificación no UTF-8 mediante
readAsText(file, 'ISO-8859-1') - URLs de datos en base64 mediante
readAsDataURL() - Mayor compatibilidad con navegadores antiguos
Para lecturas simples de texto o binarias en aplicaciones modernas, Blob.text() y Blob.arrayBuffer() son más limpios. Para vistas previas de imágenes, URL.createObjectURL(file) evita la expansión base64 y generalmente es más eficiente en memoria que readAsDataURL(). Solo recuerda llamar a URL.revokeObjectURL() cuando la URL del objeto ya no sea necesaria para evitar fugas de memoria.
Conclusión
La API FileReader sigue siendo una herramienta práctica para trabajar con objetos File en el navegador — especialmente cuando necesitas eventos de progreso, control de codificación o URLs de datos. Para casos más simples, los métodos más nuevos de Blob requieren menos código. Conoce ambos y podrás manejar cualquier escenario de lectura de archivos de manera limpia.
Preguntas Frecuentes
No. FileReader solo puede leer archivos que el usuario ha seleccionado explícitamente a través de un elemento input o interacción de arrastrar y soltar. El modelo de seguridad del navegador impide que JavaScript acceda a archivos arbitrarios en el sistema de archivos mediante rutas. Esta restricción existe para proteger la privacidad del usuario y la seguridad del sistema.
readAsArrayBuffer devuelve datos binarios sin procesar adecuados para procesamiento o manipulación, como analizar metadatos de imágenes o formas de onda de audio. readAsDataURL devuelve una cadena codificada en base64 que puedes usar directamente como src de una imagen o fondo CSS. El enfoque de URL de datos es conveniente pero produce una salida aproximadamente 33 por ciento más grande que el archivo original.
Si solo necesitas el contenido de texto y tu aplicación está dirigida a navegadores modernos, Blob.text() es más simple porque devuelve una Promise directamente. Usa FileReader cuando necesites seguimiento de progreso para archivos grandes, necesites especificar una codificación no UTF-8, o necesites soportar navegadores antiguos que carecen del método Blob.text().
Si usas URL.createObjectURL para generar una URL de vista previa, llama a URL.revokeObjectURL una vez que la imagen se haya cargado o la vista previa se haya eliminado. Si usas readAsDataURL en su lugar, la cadena base64 es gestionada automáticamente por el recolector de basura, pero consume más memoria que una URL de objeto para el mismo archivo.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.