Capítulo 12 API File – 2
La parte principal de API File es útil para cargar y procesar archivos ubicados en el ordenador del usuario, pero toma archivos que ya existen en el disco duro. No contempla la posibilidad de crear nuevos archivos o directorios. Una extensión de esta API llamada API File: Directories & System se hace cargo de esta situación. La API reserva un espacio específico en el disco duro, un espacio de almacenamiento especial en el cual la aplicación web podrá crear y procesar archivos y directorios exactamente como una aplicación de escritorio lo haría. El espacio es único y solo accesible por la aplicación que lo creó.
Para probar esta parte de la API vamos a necesitar un nuevo formulario con un campo de texto y un botón para crear y procesar archivos y directorios:
<!DOCTYPE html>
<html lang=»es»>
<head>
<title>File API</title>
<link rel=»stylesheet» href=»file.css»> <script src=»file.j s»></script>
</head>
<body>
<section id=»cajaformulario»>
<form name=»formulario»>
<p>Nombre:<br><input type=»text» name=»entrada»
id=»entrada» required></p> <p><input type=»button» name=»boton» id=»boton»
value=»Aceptar»></p>
</form>
</section>
<section id=»cajadatos»>
No hay entradas disponibles </section>
</body>
</html>
Listado 12-7. Nueva plantilla para File API: Directories & System.
Hágalo Usted Mismo: El documento HTML genera un nuevo formulario pero preserva la misma estructura y estilos CSS. Solo necesita reemplazar el código HTML anterior por el del Listado 12-7 y copiar los códigos Javascript dentro del archivo file.js para probar los siguientes ejemplos.
IMPORTANTE: El atributo request fue incluido en el elemento <input>, pero no será considerado en los códigos de este capítulo. Para volver efectivo el proceso de validación, deberemos aplicar API Forms. Lea el código del Listado 105, Capítulo 10, para encontrar un ejemplo sobre cómo hacerlo.
El espacio reservado para la aplicación es como un espacio aislado, una pequeña unidad de disco duro con su propio directorio raíz y configuración. Para comenzar a trabajar con esta unidad virtual, primero tenemos que solicitar que un Sistema de Archivos sea inicializado para nuestra aplicación.
requestFileSystem(tipo, tamaño, función éxito, función error) Este método crea el Sistema de Archivos del tamaño y tipo especificados por sus atributos. El valor del atributo tipo puede ser temporary (temporario) o persistent (persistente) de acuerdo al tiempo que deseamos que los archivos sean preservados. El atributo tamaño determina el espacio total que será reservado en el disco duro para este Sistema de Archivos en bytes. En caso de error o éxito, el método llama a las correspondientes funciones.
El método requestFileSystem() retorna un objeto FileSystem con dos propiedades:
root El valor de esta propiedad es una referencia al directorio raíz del Sistema de Archivos. Este es también un objeto DirectoryEntry (Entrada de Directorio) y tiene los métodos asignados a esta clase de objetos, como veremos más adelante. Usando esta propiedad podemos referenciar el espacio de almacenamiento y por medio de esta referencia trabajar con archivos y directorios.
name Esta propiedad retorna información acerca del Sistema de Archivos, como el nombre asignado por el navegador y su condición.
function iniciar(){
caj adatos=document.getElementByld(‘caj adatos’); var boton=document.getElementById(‘boton’); boton.addEventListener(‘click’, crear, false);
window.webkitRequestFileSystem(window.PERSISTENT, 5*1024*1024,
creardd, errores);
}
function creardd(sistema) { dd=sistema.root;
}
function crear(){
var nombre=document.getElementById(‘entrada’).value; if(nombre!=»){
dd.getFile(nombre, {create: true, exclusive: false}, mostrar,
errores);
}
}
function mostrar(entrada){
document.getElementById(‘entrada’).value=»;
caj adatos.innerHTML=’Entrada Creada!<br>’; caj adatos.innerHTML+=’Nombre: ‘+entrada.name+'<br>’ ;
caj adatos.innerHTML+=’Ruta: ‘+entrada.fullPath+'<br>’;
caj adatos.innerHTML+=’Sistema: ‘+entrada.filesystem.name;
}
function errores(e){
alert(‘Error: ‘+e.code);
}
window.addEventListener(‘load’, iniciar, false);
Listado 12-8. Creando nuestro propio Sistema de Archivos.
IMPORTANTE: Google Chrome es el único navegador en este momento con una implementación funcional de esta parte de File API. Debido a que la implementación es experimental, tuvimos que reemplazar el método requestFileSystem() por el específico de Chrome webkitRequestFileSystem(). Usando este método, podrá probar en su navegador los códigos para éste y los siguientes ejemplos. Una vez que la etapa de experimentación esté finalizada podrá volver a usar el método original.
Usando el documento HTML del Listado 12-7 y el código del Listado 12-8, obtenemos nuestra primera aplicación para trabajar con nuevos archivos en el ordenador del usuario.
El código llama al método requestFileSystem() para crear el Sistema de Archivos (u obtener una referencia si el sistema ya existe), y si esta es la primera visita, el Sistema de Archivos es creado como permanente, con un tamaño de 5 megabytes (5*1024*1024). En caso de que esta última operación sea un éxito, la función creardd() es ejecutada, continuando con el proceso de inicialización. Para controlar errores, usamos la función errores (), del mismo modo que lo hicimos para otras APIs.
Cuando el Sistema de Archivos es creado o abierto, la función creardd() recibe un objeto FileSystem y graba el valor de la propiedad root en la variable dd para referenciar el directorio raíz más adelante.
El proceso de iniciación del Sistema de Archivos ha sido finalizado. El resto de las funciones en el código del Listado 12-8 crean un nuevo archivo y muestran los datos de la entrada (un archivo o directorio) en la pantalla. Cuando el botón «Aceptar» es presionado en el formulario, la función crear() es llamada. Esta función asigna el texto insertado en el elemento <input> a la variable nombre y crea un archivo con ese nombre usando el método getFile().
Este último método es parte de la interface DirectoryEntry incluida en la API. La interface provee un total de cuatro métodos para crear y manejar archivos y directorios:
getFile(ruta, opciones, función éxito, función error) Este método crea o abre un archivo. El atributo ruta debe incluir el nombre del archivo y la ruta donde el archivo está localizado (desde la raíz de nuestro Sistema de Archivos). Hay dos banderas que podemos usar para configurar el comportamiento de este método: create y exclusive. Ambas reciben valores booleanos. La bandera create (crear) indica si el archivo será creado o no (en caso de que no exista, por supuesto), y la bandera exclusive (exclusivo), cuando es declarada como true (verdadero), fuerza al método getFile () a retornar un error si intentamos crear un archivo que ya existe. Este método también recibe dos funciones para responder en case de éxito o error. getDirectory(ruta, opciones, función éxito, función error) Este método tiene exactamente las mismas características que el anterior pero es exclusivo para directorios (carpetas). createReader() Este método retorna un objeto DirectoryReader para leer entradas desde un directorio específico.
removeRecursively() Este es un método específico para eliminar directorios y todo su contenido.
En el código del Listado 12-8, el método getFile () usa el valor de la variable nombre para crear u obtener el archivo. El archivo será creado si no existe (create: true) o será leído en caso contrario (exclusive: false). La función crear () también controla que el valor de la variable nombre no sea una cadena vacía antes de ejecutar getFile ().
El método getFile () usa dos funciones, mostrar () y errores (), para responder al éxito o fracaso de la operación. La función mostrar () recibe un objeto Entry (entrada) y muestra el valor de sus propiedades en la pantalla. Este tipo de objetos tiene varios métodos y propiedades asociadas que estudiaremos más adelante. Por ahora hemos aprovechado solo las propiedades name, fullPath y filesystem.
El método getFile() (específico para archivos) y el método getDirectory() (específico para directorios) son exactamente iguales. Para crear un directorio (carpeta) en nuestro Sistema de Archivos del ejemplo anterior, solo tenemos que reemplazar el nombre getFile () por getDirectory (), como es mostrado en el siguiente código:
function crear(){
var nombre=document.getElementById(‘entrada’).value; if(nombre!=»){
dd.getDirectory(nombre, {create: true, exclusive: false},
mostrar, errores);
}
}
Listado 12-9. Usando getDirectory() para crear un directorio.
Ambos métodos son parte del objeto DirectoryEntry llamado root, que estamos representando con la variable dd, por lo que siempre deberemos usar esta variable para llamar a los métodos y crear archivos y directorios en el Sistema de Archivos de nuestra aplicación.
Hágalo usted mismo: Use la función en el Listado 12-9 para reemplazar la función crear () del Listado 12-8 y así crear directorios en lugar de archivos. Suba los archivos a su servidor, abra el documento HTML del Listado 12-7 en su navegador y cree un directorio usando el formulario en la pantalla.
Como mencionamos antes, el método createReader() nos permite acceder a una lista de entradas (archivos y directorios) en una ruta específica. Este método retorna un objeto DirectoryReader que contiene el método readEntries () para leer las entradas obtenidas:
readEntries(función éxito, función error) Este método lee el siguiente bloque de entradas desde el directorio seleccionado. Cada vez que el método es llamado, la función utilizada para procesar operaciones exitosas retorna un objeto con la lista de entradas o el valor null si no se encontró ninguna.
El método readEntries () lee la lista de entradas por bloque. Como consecuencia, no existe garantía alguna de que todas las entradas serán retornadas en una sola llamada. Tendremos que llamar al método tantas veces como sea necesario hasta que el objeto retornado sea un objeto vacío.
Además, deberemos hacer otra consideración antes de escribir nuestro próximo código. El método createReader() retorna un objeto DirectoryReader para un directorio específico. Para obtener los archivos que queremos, primero tenemos que obtener el correspondiente objeto Entry del directorio que queremos leer usando el ya conocido método getDirectory () :
function iniciar(){
caj adatos=document.getElementByld(‘caj adatos’);
var boton=document.getElementById(‘boton’);
boton.addEventListener(‘click’, crear, false);
window.webkitRequestFileSystem(window.PERSISTENT, 5*1024*1024,
creardd, errores);
}
function creardd(sistema) { dd=sistema.root; ruta=»;
mostrar();
}
function errores(e){
alert(‘Error: ‘+e.code);
}
function crear(){
var nombre=document.getElementById(‘entrada’).value;
if(nombre!=»){
nombre=ruta+nombre;
dd.getFile(nombre, {create: true, exclusive: false}, mostrar,
errores);
}
}
function mostrar(){
document.getElementById(‘entrada’).value=»; caj adatos.innerHTML=’ ‘;
dd.getDirectory(ruta,null,leerdir,errores);
}
function leerdir(dir){
var lector=dir.createReader();
var leer=function(){
lector.readEntries(function(archivos){ if(archivos.length){ listar(archivos);
leer();
}
}, errores);
}
leer();
}
function listar(archivos){
for(var i=0; i<archivos.length; i++) {
if(archivos[i].isFile) {
caj adatos.innerHTML+=archivos[i].name+'<br>’;
}else if(archivos[i].isDirectory){ cajadatos.innerHTML+='<span onclick=
«cambiardir(\»+archivos[i].name+’\’)» class=»directorio»>+’+archivos[i].name+'</span><br>’;
}
}
}
function cambiardir(nuevaruta){ ruta=ruta+nuevaruta+’/’; mostrar();
}
window.addEventListener(‘load’, iniciar, false);
Listado 12-10. Sistema de Archivos completo.
Este código no reemplazará al Explorador de Archivos de Windows, pero al menos provee toda la información que necesitamos para entender cómo construir un Sistema de Archivos útil y funcional para la web. Vamos a analizarlo parte por parte.
La función iniciar() hace lo mismo que en códigos previos: inicia o crea el Sistema de Archivos y llama a la función creardd () si tiene éxito. Además de declarar la variable dd para referenciar el directorio raíz de nuestro disco duro virtual, la función creardd () también inicializa la variable ruta con una cadena de texto vacía (representando el directorio raíz) y llama a la función mostrar() para mostrar la lista de entradas en pantalla tan pronto como la aplicación es cargada.
La variable ruta será usada en el resto de la aplicación para conservar el valor de la ruta actual dentro de Sistema de Archivos en la que el usuario está trabajando. Para entender su importancia, puede ver cómo la función crear () fue modificada en el código del Listado 12-10 para usar este valor y así crear nuevos archivos en la ruta correspondiente (dentro del directorio seleccionado por el usuario). Ahora, cada vez que un nuevo nombre de archivo es enviado desde el formulario, la ruta es agregada al nombre y el archivo es creado en el directorio actual.
Como ya explicamos, para mostrar la lista de entradas, debemos primero abrir el directorio a ser leído. Usando el método getDirectory() en la función mostrar(), el directorio actual (de acuerdo a la variable ruta) es abierto y una referencia a este directorio es enviada a la función leerdir() si la operación es exitosa. Esta función guarda la referencia en la variable dir, crea un nuevo objeto DirectoryReader para el directorio actual y obtiene la lista de entradas con el método readEntries ().
En leerdir(), funciones anónimas son usadas para mantener el código organizado y no superpoblar el entorno global. En primer lugar, createReader() crea un objeto DirectoryReader para el directorio representado por dir. Luego, una nueva función llamada leer() es creada dinámicamente para leer las entradas usando el método readEntries(). Este método lee las entradas por bloque, lo que significa que debemos llamarlo varias veces para asegurarnos de que todas las entradas disponibles en el directorio son leídas. La función leer () nos ayuda a lograr este propósito. El proceso es el siguiente: al final de la función leerdir (), la función leer () es llamada por primera vez. Dentro de la función leer() llamamos al método readEntries(). Este método usa otra función anónima en caso de éxito para recibir el objeto files y procesar su contenido (archivos). Si este objeto no está vacío, la función listar() es llamada para mostrar en pantalla las entradas leídas, y la función leer() es ejecutada nuevamente para obtener el siguiente bloque de entradas (la función se llama a sí misma una y otra vez hasta que ninguna entrada es retornada).
La función listar() está a cargo de imprimir la lista de entradas (archivos y directorios) en pantalla. Toma el objeto files y comprueba las características de cada entrada usando dos propiedades importantes de la interface Entry: isFile e isDirectory. Como sus nombres en inglés indican, estas propiedades contienen valores booleanos para informar si la entrada es un archivo o un directorio. Luego de que esta condición es controlada, la propiedad name es usada para mostrar información en la pantalla.
Existe una diferencia en cómo nuestra aplicación mostrará un archivo o un directorio en la pantalla. Cuando una entrada es detectada como directorio, es mostrada a través de un elemento <span> con un manejador de eventos onclick que llamará a la función cambiardir () si el usuario hace clic sobre el mismo. El propósito de esta función es declarar la nueva ruta actual para apuntar al directorio seleccionado. Recibe el nombre del directorio, agrega el directorio al valor de la variable ruta y llama a la función mostrar () para actualizar la información en pantalla (ahora deberían verse las entradas dentro del nuevo directorio seleccionado). Esta característica nos permite abrir directorios y ver su contenido con solo un clic del ratón, exactamente como una explorador de archivos común y corriente haría.
Este ejemplo no contempla la posibilidad de retroceder en la estructura para ver el contenido de directorios padres. Para hacerlo, debemos aprovechar otro método provisto por la interface Entry:
getParent(función éxito, función error) Este método retorna un objeto Entry del directorio que contiene la entrada seleccionada. Una vez que obtenemos el objeto Entry podemos leer sus propiedades para obtener toda la información acerca del directorio padre de esa entrada en particular.
Cómo trabajar con el método getParent() es simple: supongamos que una estructura de directorios como fotos/misvacaciones fue creada y el usuario está listando el contenido de misvacaciones en este momento. Para regresar al directorio fotos, podríamos incluir un enlace en el documento HTML con un manejador de eventos onclick que llame a la función encargada de modificar la ruta actual para apuntar a esta nueva dirección (el directorio fotos). La función llamada al hacer clic sobre el enlace podría ser similar a la siguiente:
function volver(){
dd.getDirectory(ruta,null,function(dir){ dir.getParent(function(padre) { ruta=padre.fullPath; mostrar();
}, errores);
},errores);
}
Listado 12-11. Regresando al directorio padre.
La función volver() en el Listado 12-11 cambia el valor de la variable ruta para apuntar al directorio padre del directorio actual. Lo primero que hacemos es obtener una referencia del directorio actual usando el método getDirectory(). Si la operación es exitosa, una función anónima es ejecutada. En esta función, el método getParent () es usado para encontrar el directorio padre del directorio referenciado por dir (el directorio actual). Si esta operación es exitosa, otra función anónima es ejecutada para recibir el objeto padre y declarar el valor de la ruta actual igual al valor de la propiedad fullPath (esta propiedad contiene la ruta completa hacia el directorio padre). La función mostrar () es llamada al final del proceso para actualizar la información en pantalla (mostrar las entradas ubicadas en la nueva ruta).
Por supuesto, esta aplicación puede ser extremadamente enriquecida y mejorada, pero eso es algo que dejamos en sus manos.
Hágalo Usted Mismo: Agregue la función del Listado 12-11 al código del Listado 12-10 y cree un enlace en el documento HTML para llamar a esta función (por ejemplo, <span onclick=»volver () «>volver</span>).
Ya mencionamos que la interface Entry incluye un grupo de propiedades y métodos para obtener información y operar archivos. Muchas de las propiedades disponibles ya fueron usadas en previos ejemplos. Ya aprovechamos las propiedades isFile e isDirectory para comprobar la clase de entrada, y también usamos los valores de name, fullPath y filesystem para mostrar información sobre la entrada en pantalla. El método getParent (), estudiado en el último código, es también parte de esta interface. Sin embargo, existen todavía algunos métodos más que son útiles para realizar operaciones comunes sobre archivos y directorios. Usando estos métodos podremos mover, copiar y eliminar entradas exactamente como en cualquier aplicación de escritorio:
moveTo(directorio, nombre, función éxito, función error) Este método mueve una entrada a una ubicación diferente en el Sistema de Archivos. Si el atributo nombre es provisto, el nombre de la entrada será cambiado a este valor.
copyTo(directorio, nombre, función éxito, función error) Este método genera una copia de una entrada en otra ubicación dentro del Sistema de Archivos. Si el atributo nombre es provisto, el nombre de la nueva entrada será cambiado a este valor. remove() Este método elimina un archivo o un directorio vacío (para eliminar un directorio con contenido, debemos usar el método removeRecursively() presentado anteriormente).
Necesitaremos una nueva plantilla para probar estos métodos. Para simplificar los códigos, vamos a crear un formulario con solo dos campos, uno para el origen y otro para el destino de cada operación:
<!DOCTYPE html>
<html lang=»es»>
<head>
<title>File API</title>
<link rel=»stylesheet» href=»file.css»>
<script src=»file.j s»></script>
</head>
<body>
<section id=»cajaformulario»>
<form name=»formulario»>
<p>Origen:<br><input type=»text» name=»origen» id=»origen»
required></p>
<p>Destino:<br><input type=»text» name=»destino»
id=»destino» required></p> <p><input type=»button» name=»boton» id=»boton»
value=»Aceptar»></p>
</form>
</section>
<section id=»caj adatos»></section>
</body>
</html>
Listado 12-12: nueva plantilla para operar con archivos
Moviendo
El método moveTo() requiere un objeto Entry para el archivo y otro para el directorio en donde el archivo será movido. Por lo tanto, primero tenemos que crear una referencia al archivo que vamos a mover usando getFile(), luego obtenemos la referencia del directorio destino con getDirectory (), y finalmente aplicamos moveTo () con esta información:
function iniciar(){
caj adatos=document.getElementById(‘caj adatos’);
var boton=document.getElementById(‘boton’);
boton.addEventListener(‘click’, modificar, false);
window.webkitRequestFileSystem(window.PERSISTENT, 5*1024*1024,
creardd, errores);
}
function creardd(sistema){
dd=sistema.root;
ruta=»;
mostrar();
}
function errores(e){
alert(‘Error: ‘+e.code);
}
function modificar() {
var origen=document.getElementById(‘origen’).value;
var destino=document.getElementById(‘destino’).value;
dd.getFile(origen,null,function(archivo){ dd.getDirectory(destino,null,function(dir){ archivo.moveTo(dir,null,exito, errores) ;
},errores);
},errores);
}
function exito(){
document.getElementById(‘origen’).value=»; document.getElementById(‘destino’).value=»; mostrar();
}
function mostrar(){
caj adatos.innerHTML=’ ‘;
dd.getDirectory(ruta,null,leerdir,errores);
}
function leerdir(dir){
var lector=dir.createReader(); var leer=function(){
lector.readEntries(function(archivos){
if(archivos.length){
listar(archivos);
leer();
}
}, errores);
}
leer();
}
function listar(archivos){
for(var i=0; i<archivos.length; i++) {
if(archivos[i].isFile) {
cajadatos.innerHTML+=archivos[i].name+'<br>’;
}else if(archivos[i].isDirectory){
caj adatos.innerHTML+='<span onclick=
«cambiardir(\»+archivos[i].name+’\’)» class=»directorio»>+’+archivos[i].name+'</span><br>’;
}
}
}
function cambiardir(nuevaruta){ ruta=ruta+nuevaruta+ mostrar();
}
window.addEventListener(‘load’, iniciar, false);
Listado 12-13. Moviendo archivos.
En este último ejemplo, usamos funciones de códigos previos para crear o abrir nuestro Sistema de Archivos y mostrar el listado de entradas en pantalla. La única función nueva en el Listado 12-13 es modificar (). Esta función toma los valores de los campos del formulario origen y destino y los utiliza para abrir el archivo original y luego, si la operación es exitosa, abrir el directorio de destino. Si ambas operaciones son exitosas el método moveTo() es aplicado sobre el objeto file y el archivo es movido al directorio representado por dir. Si esta última operación es exitosa, la función exito() es llamada para vaciar los campos en el formulario y actualizar las entradas en pantalla ejecutando la función mostrar().
Hágalo usted mismo: Para probar este ejemplo necesita un archivo HTML con la plantilla del Listado 12-12, el archivo CSS usado desde el comienzo de este capítulo, y un archivo llamado file.js con el código del Listado 12-13 (recuerde subir los archivos a su servidor). Cree archivos y directorios usando códigos previos para tener entradas con las que trabajar. Utilice el formulario del último documento HTML para insertar los valores del archivo a ser movido (con la ruta completa desde la raíz) y el directorio en el cual el archivo será movido (si el directorio se encuentra en la raíz del Sistema de Archivos no necesita usar barras, solo su nombre).
Por supuesto, la única diferencia entre el método moveTo() y el método copyTo() es que el último preserva el archivo original. Para usar el método copyTo(), solo debemos cambiar el nombre del método en el código del Listado 12-13. La función modificar() quedará como en el siguiente ejemplo:
function modificar() {
var origen=document.getElementById(‘origen’).value; var destino=document.getElementById(‘destino’).value;
dd.getFile(origen,null,function(archivo){
dd.getDirectory(destino,null,function(dir){
archivo.copyTo(dir,null,exito, errores) ;
},errores);
},errores);
}
Listado 12-14. Copiando archivos.
Hágalo usted mismo: Reemplace la función modificar() del Listado 12-13 con esta última y abra la plantilla del Listado 12-12 para probar el código. Para copiar un archivo, debe repetir los pasos usados previamente para moverlo. Inserte la ruta del archivo a copiar en el campo origen y la ruta del directorio donde desea generar la copia en el campo destino.
Eliminar archivos y directorio es incluso más sencillo que mover y copiar. Todo lo que tenemos que hacer es obtener un objeto Entry del archivo o directorio que deseamos eliminar y aplicar el método remove () a esta referencia:
function modificar(){
var origen=document.getElementByld(‘origen’).value;
var origen=ruta+origen;
dd.getFile(origen,null,function(entrada){ entrada.remove(exito,errores);
},errores);
}
Listado 12-15. Eliminando archivos y directorios.
El código del Listado 12-15 solo utiliza el valor del campo origen del formulario. Este valor, junto con el valor de la variable ruta, representará la ruta completa de la entrada que queremos eliminar. Usando este valor y el método getFile() creamos un objeto Entry para la entrada y luego aplicamos el método remove ().
Hágalo usted mismo: Reemplace la función modificar() en el código del Listado 12-13 con la nueva del Listado 12-15. Esta vez solo necesita ingresar el valor del campo origen para especificar el archivo a ser eliminado.
Para eliminar un directorio en lugar de un archivo, el objeto Entry debe ser creado para ese directorio usando getDirectory(), pero el método remove() trabaja exactamente igual sobre un tipo de entrada u otro. Sin embargo, debemos considerar una situación con respecto a la eliminación de directorios: si el directorio no está vacío, el método remove () retornará un error. Para eliminar un directorio y su contenido, todo al mismo tiempo, debemos usar otro método mencionado anteriormente llamado removeRecursively() :
function modificar(){
var destino=document.getElementById(‘destino’).value; dd.getDirectory(destino,null,function(entrada){
entrada.removeRecursively(exito,errores);
},errores);
}
Listado 12-16. Eliminando directorios no vacíos.
En la función del Listado 12-16 usamos el valor del campo destino para indicar el directorio a ser eliminado. El método removeRecursively () eliminará el directorio y su contenido en una sola ejecución y llamará a la función exito() si la operación es realizada con éxito.
Hágalo usted mismo: Las funciones modificar() presentadas en los Listados 1214, 12-15 y 12-16 fueron construidas para reemplazar la misma función en el Listado 12-13. Para ejecutar estos ejemplos, utilice el código del Listado 12-13, reemplace la función modificar () por la que quiere probar y abra la plantilla del Listado 12-12 en su navegador. De acuerdo al método elegido, deberá ingresar uno o dos valores en el formulario.