7 days of WordPress plugins, themes & templates - for free!* Unlimited asset downloads! Start 7-Day Free Trial
Advertisement
  1. Code
  2. HTML & CSS

Jugando con la API del sistema de archivos HTML5

Scroll to top
Read Time: 11 mins

Spanish (Español) translation by Steven (you can also view the original English article)

HTML5 nos brinda una gran variedad de nuevas posibilidades, como dibujar con canvas, implementar multimedia con las API de audio y video, etc. Una de estas herramientas, que todavía es relativamente nueva, es la API del sistema de archivos. Nos da acceso a una sección de espacio aislado del sistema de archivos local del usuario, lo que llena aún más la brecha entre las aplicaciones web y de escritorio. En el tutorial de hoy, repasaremos los conceptos básicos de esta nueva y emocionante API, explorando las tareas más comunes del sistema de archivos. ¡Empecemos!


Introducción

Ya no es necesario descargar e instalar un software determinado para poder utilizarlo. Simplemente un navegador web y una conexión a Internet nos brindan la capacidad de utilizar cualquier aplicación web, en cualquier momento, en cualquier lugar y en cualquier plataforma.

En resumen, las aplicaciones web son geniales; pero, en comparación con las aplicaciones de escritorio, todavía tienen una debilidad significativa: no tienen una forma de interactuar y organizar los datos en una jerarquía estructurada de carpetas: un sistema de archivos real. Afortunadamente, con la nueva API del sistema de archivos, esto se puede cambiar. Esta API brinda a las aplicaciones web acceso controlado a un sistema de archivos local privado "sandbox", en el que pueden escribir y leer archivos, crear y enumerar directorios, etc. Aunque en el momento de escribir este artículo solo el navegador Chrome de Google admite la implementación "completa" de la API del sistema de archivos, todavía merece ser estudiada como una forma poderosa y conveniente de almacenamiento local.

Can I Use SupportCan I Use SupportCan I Use Support

La API del sistema de archivos viene en dos versiones diferentes. La API asíncrona, que es útil para aplicaciones normales, y la API síncrona, reservada para su uso con trabajadores web. Para los propósitos de este tutorial, exploraremos exclusivamente la versión asincrónica de la API.


Paso 1 - Comenzando

Tu primer paso es obtener acceso al sistema de archivos HTML5 solicitando un objeto del sistema llamado LocalFile, utilizando el método global window.requestFileSystem():

No hay forma de que una aplicación web "salga" más allá del directorio raíz local.

Como los dos primeros parámetros, especifica la vida útil y el tamaño del sistema de archivos que deseas. Un sistema de archivos PERSISTENTE es adecuado para aplicaciones web que desean almacenar datos de usuario de forma permanente. El navegador no lo eliminará, excepto por solicitud explícita del usuario. Un sistema de archivos TEMPORAL es apropiado para aplicaciones web que desean almacenar datos en caché, pero aún pueden funcionar si el navegador web elimina el sistema de archivos. El tamaño del sistema de archivos se especifica en bytes y debe ser un límite superior razonable a la cantidad de datos que necesitas almacenar.

El tercer parámetro es una función de devolución de llamada que se activa cuando el agente de usuario proporciona con éxito un sistema de archivos. Su argumento es un objeto FileSystem. Y, por último, podemos agregar una función de devolución de llamada opcional, que se llama cuando ocurre un error o se deniega la solicitud de un sistema de archivos. Su argumento es un objeto FileError. Aunque este parámetro es opcional, siempre es una buena idea detectar errores para los usuarios, ya que hay varios lugares donde las cosas pueden salir mal.

El sistema de archivos obtenido con estas funciones depende del origen del documento que lo contiene. Todos los documentos o aplicaciones web del mismo origen (host, puerto y protocolo) comparten un sistema de archivos. Dos documentos o aplicaciones de diferentes orígenes tienen sistemas de archivos completamente distintos e inconexos. Un sistema de archivos está restringido a una sola aplicación y no puede acceder a los datos almacenados de otra aplicación. También está aislado del resto de archivos en el disco duro del usuario, lo cual es bueno: no hay forma de que una aplicación web "salga" más allá del directorio raíz local o acceda a archivos arbitrarios.

Repasemos un ejemplo:

Esto crea un sistema de archivos temporal con 5MB de almacenamiento. Luego proporciona una función de devolución de llamada exitosa, que usaremos para operar nuestro sistema de archivos. Y, por supuesto, también se agrega un controlador de errores, en caso de que algo salga mal. Aquí, la función errorHandler() es demasiado genérica. Entonces, si lo deseas, puedes crear una versión ligeramente optimizada, que le da al lector un mensaje de error más descriptivo:

El objeto 'filesystem' que obtienes tiene un nombre (name) (un nombre único para el sistema de archivos, asignado por el navegador) y una propiedad root que se refiere al directorio raíz del sistema de archivos. Este es un objeto DirectoryEntry y puede tener directorios anidados que están representados por objetos DirectoryEntry. Cada directorio del sistema de archivos puede contener archivos, representados por objetos FileEntry. El objeto DirectoryEntry define métodos para obtener objetos DirectoryEntry y FileEntry por nombre de ruta (opcionalmente crearán nuevos directorios o archivos si especificas un nombre que no existe). DirectoryEntry también define un método de fábrica createReader() que devuelve un objeto DirectoryReader para enumerar el contenido de un directorio. La clase FileEntry define un método para obtener el objeto File (un Blob) que representa el contenido de un archivo. Puedes utilizar después un objeto FileReader para leer el archivo. FileEntry define otro método para devolver un objeto FileWriter que puedes usar para escribir contenido en un archivo.

Uf... suena complicado. ¿No? No te preocupes. Todo se aclarará a medida que avancemos en los siguientes ejemplos.


Paso 2: Trabajar con directorios

Obviamente, lo primero que necesitas crear en un sistema de archivos son algunos depósitos o directorios. Aunque el directorio raíz ya existe, no vas a querer colocar todos tus archivos allí. Los directorios son creados por el objeto DirectoryEntry. En el siguiente ejemplo, creamos un directorio, llamado Documents, dentro del directorio raíz:

El método getDirectory() se usa tanto para leer como para crear directorios. Como primer parámetro, puedes pasar un nombre o una ruta como directorio a buscar o crear. Establecemos el segundo argumento en true, porque estamos intentando crear un directorio, no leer uno existente. Y al final, agregamos una devolución de llamada de error.

Hasta aquí todo bien. Tenemos un directorio; agreguemos ahora un subdirectorio. La función es exactamente la misma con una diferencia: cambiamos el primer argumento de 'Documents' a 'Documents/Music'. Suficientemente fácil; pero, ¿qué sucede si deseas crear una subcarpeta, por ejemplo Sky, con dos carpetas principales, Images y Nature, dentro de la carpeta Documents? Si escribes 'Documents/Images/Nature/Sky' para el argumento de la ruta, recibirás un error, porque no puedes crear un directorio, cuando su padre inmediato no existe. Una solución para esto es crear cada carpeta una por una: Images dentro de DocumentsNature dentro de Images y luego Sky dentro de Nature. Pero este es un proceso muy lento e inconveniente. Hay una solución mejor: crear una función que creará todas las carpetas necesarias automáticamente.

Con este pequeño truco, todo lo que tenemos que hacer es proporcionar una ruta completa que represente las carpetas que queremos crear. Ahora, el directorio Sky se creó con éxito y puedes crear otros archivos o directorios dentro de él.

Ahora es el momento de comprobar lo que tenemos en nuestro sistema de archivos. Crearemos un objeto DirectoryReader y usaremos el método readEntries() para leer el contenido del directorio.

En el código anterior, las propiedades isDirectory e isFile se utilizan para obtener una salida diferente para directorios y archivos, respectivamente. Además, usamos la propiedad fullPath para obtener la ruta completa de la entrada, en lugar de solo su nombre.

Hay dos formas de eliminar un DirectoryEntry del sistema de archivos: remove() y removeRecursively(). El primero elimina un directorio determinado solo si está vacío. De lo contrario, recibirá un error.

Si la carpeta Music tiene archivos, entonces debes usar el segundo método, que borra de forma recursiva el directorio y todo su contenido.


Paso 3: Trabajar con archivos

Ahora que sabemos cómo crear directorios, ¡es hora de poblarlos con archivos!

El siguiente ejemplo crea un archivo test.txt vacío en el directorio raíz:

El primer argumento de getFile() puede ser una ruta absoluta o relativa, pero debe ser válida. Por ejemplo, es un error intentar crear un archivo, cuando su padre inmediato no existe. El segundo argumento es un objeto literal, que describe el comportamiento de la función si el archivo no existe. En este ejemplo, create: true crea el archivo si no existe y arroja un error si existe (exclusive: true). De lo contrario, si create: false, el archivo simplemente se recupera y se devuelve.

Sin embargo, tener un archivo vacío no es muy útil; así que agreguemos algo de contenido adentro. Podemos usar el objeto FileWriter para esto.

Arriba, recuperamos el archivo test.txt y creamos un objeto FileWriter para él. Luego le agregamos contenido creando un nuevo objeto BlobBuilder y usando el método write() de FileWriter.

Llamar a getFile() solo recupera un FileEntry. No devuelve el contenido del archivo. Entonces, si queremos leer el contenido del archivo, necesitamos usar el objeto File y el objeto FileReader.

Hemos escrito algo de contenido en nuestro archivo, pero ¿qué pasa si deseas agregar más en una fecha posterior? Para agregar datos a un archivo existente, se usa FileWriter una vez más. Podemos reposicionar el escritor al final del archivo, usando el método seek(). seek acepta un desplazamiento de bytes como argumento y establece la posición del escritor del archivo en ese desplazamiento.

Para eliminar un archivo del sistema de archivos, simplemente llama a entry.remove(). El primer argumento de este método es una función de devolución de llamada de parámetro cero, que se llama cuando el archivo se elimina correctamente. El segundo es una devolución de llamada de error opcional si se produce algún error.


Paso 4: Manipulación de archivos y directorios

FileEntry y DirectoryEntry comparten los mismos métodos de API para copiar, mover y cambiar el nombre de las entradas. Hay dos métodos que puedes utilizar para estas operaciones: copyTo() y moveTo(). Ambos aceptan exactamente los mismos parámetros:

El primer parámetro es la carpeta principal a la cual mover/copiar la entrada. El segundo es un nuevo nombre opcional para dar a la entrada movida/copiada, que en realidad se requiere cuando copias una entrada en la misma carpeta; de lo contrario, obtendrás un error. El tercer y cuarto parámetros se explicaron anteriormente.

Repasemos algunos ejemplos sencillos. En el siguiente, copiamos el archivo test.txt de la raíz (root) al directorio Documents.

El siguiente ejemplo mueve test.txt a Documents, en lugar de copiarlo:

El siguiente ejemplo cambia el nombre de test.txt a text.txt:


Aprende más

En este tutorial introductorio, solo hemos arañado la superficie de las diferentes interfaces del sistema de archivos. Si deseas obtener más información y profundizar en la API del sistema de archivos, debes consultar las especificaciones de especificaciones de W3C:

Ahora que tienes una comprensión básica de lo que es la API del sistema de archivos y cómo se puede usar, debería ser considerablemente más fácil comprender la documentación de la API, que puede resultar un poco confusa a primera vista.


Conclusión

La API del sistema de archivos es una tecnología potente y fácil de usar, que proporciona a los desarrolladores web una gran variedad de nuevas posibilidades al crear aplicaciones web. Es cierto que todavía es bastante nueva y no es ampliamente compatible con todos los navegadores principales, pero esto ciertamente cambiará en el futuro. ¡También podrías empezar con ventaja!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.