Tarde o temprano toca trabajar con archivos, ya sea para guardar los datos generados por tu aplicación, abrir los documentos creados con otros programas o bien porque sea la principal función de la herramienta que estás desarrollando: copiar, mover, borrar, examinar… archivos. Para todo ello Xojo ofrece la clase FolderItem, armada con una buena cantidad de propiedades que nos permiten examinar los atributos del fichero en cuestión, como por ejemplo fecha de creación y modificación, la ruta al archivo (en varios formatos), si es un alias, etc.; así como los métodos que ponen en nuestras manos las operaciones que podemos hacer sin esfuerzo.
Por supuesto, la clase FolderItem está disponible bajo todas las plataformas de despliegue soportadas por Xojo, ya sea en aplicaciones Desktop (macOS, Windows, Linux, Raspberry Pi), Consola, Web o iOS, si bien en este último caso, atendiendo a las limitaciones lógicas de Sandbox impuestas por la propia Apple a los desarrolladores para el despliegue, distribución e instalación de aplicaciones sobre los dispositivos; ya se sabe, además de que no se pueden modificar (escribir) sobre los archivos contenidos en el Bundle (carpeta) de la aplicación, también hay que tener en cuenta las restricciones sobre a qué directorios se puede acceder y a cuales no.
Tal y como ocurre con el uso de cualquier otra clase, lo primero que querremos realizar en este caso es obtener una instancia de la clase (objeto) hacia el elemento con el que deseemos trabajar, ya se trate de un archivo ya existente en disco duro —por ejemplo para operaciones de lectura o bien copiarlo, entre otras posibles operaciones—, o bien para un archivo que estemos creando. En ambos casos, la forma de hacerlo es la misma:
Dim f as new FolderItem("/users/myusuario/documents/test.txt")
En este caso estaremos utilizando el Constructor implementado por la clase FolderItem, pasando como argumento la ruta nativa hacia el archivo al que deseamos apuntar, si existe; o bien para crear el archivo en el caso de que lo vayamos a crear desde nuestra aplicación. Es importante incidir en el hecho de que el formato de la ruta como String es nativa a la plataforma sobre la que se vaya a ejecutar la aplicación, algo que debe de tenerse en consideración por ejemplo en los casos en los que se trate de una aplicación multiplataforma. Si es así, puedes solventar el manejo de la ruta mediante el uso de la cláusula condicional de compilación #If…#Then…#Endif.
Adicionalmente, cuando utilizamos rutas absolutas en el constructor no nos asegura que obtengamos una referencia válida, apuntada en este caso por la variable ‘f’. Por ejemplo, si estuviésemos intentando abrir un archivo es posible que el archivo ya no esté allí (movido, eliminado…); o bien también es posible que hayamos cometido algún error a la hora de teclear la ruta propiamente dicha. Por tanto, es más que recomendable realizar una comprobación sobre la validez de la instancia antes de proceder a trabajar con ella.
Por ejemplo, algo tan sencillo como:
if f <> Nil then
// es una referencia válida
// procedemos a trabajar sobre ella
end
O bien mediante la gestión de excepciones, como en el siguiente ejemplo:
Exception e as NilObjectException
MsgBox “The file is not valid”
Ahora bien, ¿cómo podemos obtener una referencia a un archivo en aquellos casos en los que no conocemos previamente la ruta? Es decir, esto es lo que ocurre, por ejemplo, en la mayoría de las aplicaciones donde se brinda al usuario de la aplicación la opción de que sea él quien elija el archivo a través de lo que se denomina un Cuadro de Diálogo; es decir, una ventana que da acceso al sistema de archivos del ordenador, donde el usuario puede seleccionar cualquier archivo compatible con la aplicación.
Selección de archivos: GetOpenFolderItem
Para estas situaciones, siendo además lo que probablemente quieras implementar en la mayoría de los casos, Xojo proporciona la función GetOpenFolderItem, sobre la que hemos de pasar como único parámetro una cadena que represente, a modo de filtro, los tipos de archivos en los que nuestra aplicación está interesada. De ser así, el cuadro de diálogo estándar mostrado al usuario mostrará como seleccionables únicamente aquellos archivos que sean compatibles, mientras que el resto aparecerán en modo fantasma. También podemos prescindir de cualquier tipo de filtro para los archivos seleccionables, en cuyo caso nos limitaremos a pasar “????” como parámetro de la función.
Como resultado de la invocación de esta función obtendremos un FolderItem. Por ejemplo:
Dim f a FolderItem = GetOpenFolderItem("????")
MsgBox f.path
Ahora bien, en la interacción con el Cuadro de Diálogo el usuario de nuestra aplicación puede haber seleccionado un archivo pulsando a continuación el botón ‘OK’, en cuyo caso obtendremos una instancia FoldeItem con una referencia válida; o bien es posible que haya cancelado la operación, pulsando para ello el botón ‘Cancel’, en cuyo caso nuestra instancia, representada por la variable ‘f’ no sería válida sino que apuntará a Nil. Por tanto, es preciso aplicar las mismas comprobaciones sobre la validez de la instancia vistas en el apartado anterior.
SpecialFolder: acceso a directorios específicos
Una tercera vía que pone Xojo en nuestras manos para obtener referencias a archivos de una forma rápida es mediante SpecialFolder. Se trata de un módulo que proporciona acceso a ubicaciones específicas del sistema de archivos correspondiente al sistema operativo sobre el que se esté ejecutando la aplicación, haciendo que resulte especialmente adecuado su uso a la hora de guardar o acceder a archivos en la carpeta designada de Documentos, por ejemplo, o bien para acceder a las rutas específicas de Librerías o Cachés, entre otras.
Por ejemplo, si quisiéramos obtener una referencia correcta a la carpeta de Documentos en cada una de las plataformas de despliegue soportadas, podríamos utilizar lo siguiente:
Dim docs As Xojo.IO.FolderItem
docs = Xojo.IO.SpecialFolder.Documents
msgbx docs.path
Prueba a ejecutar el anterior fragmento de código sobre diferentes sistemas operativos, y observarás que en cada caso siempre obtendrás el mensaje mostrando la ruta correcta.
Child: añadir elementos a una ruta FolderItem
En el anterior apartado hemos visto como podemos obtener la ruta a una carpeta o directorio; pero, ¿cómo podemos completar la ruta hasta indicar un archivo específico, ya existente o bien que queremos crear? Para ello contamos con el método de instancia de clase [Child](http://developer.xojo.com/xojo-io-folderitem$Child). Mediante el uso de este método de instancia de clase podemos añadir tantos nuevos componentes (por ejemplo niveles de carpetas/directorios en la jerarquía) como deseemos hasta indicar el archivo final del que deseamos obtener una referencia válida. Por ejemplo:
Using Xojo.IO
Dim docs as FolderItem = SpecialFolder.Documents
docs = docs.child(“MyFile.txt”)
O bien:
Using Xojo.IO
Dim docs as FolderItem = SpecialFolder.Documents
docs = docs.child(“Recipes”).child(“MyRecipe.doc”)
En el primero de los ejemplos, la referencia apunta finalmente a un archivo mediante el uso del método Child, mientras que en el segundo se incorpora también un directorio adicional (“Recipes”) como parte de la ruta mediante Child hasta llegar al archivo final. En ambos casos, puede que se trate de un archivo ya existente o bien uno que va a crear nuestra aplicación, en cuyo caso las propiedades de la variable ‘docs’ no tendrá valores válidos en todas las propiedades que sí se pueden consultar cuando se apunta a un archivo ya creado. Por ejemplo, algunas de estas propiedades son la fecha de creación, fecha de modificación o tamaño de archivo, entre otras. En los casos en los que se apunte a un directorio o carpeta también podemos utilizar la propiedad Count para conocer la cantidad de elementos contenidos, de modo que nos resulte más sencillo iterar por ellos, por ejemplo.
Iterar elementos
Sin embargo, cuando se trata de iterar por los elementos de una carpeta, por ejemplo para operar sobre cada uno de los archivos disponibles o bien profundizar más en la jerarquía de archivos recorriendo cada una de las carpetas encontradas, lo mejor es obtener un iterador sobre la carpeta/directorio que utilicemos como raíz del proceso. Para ello, la clase Xojo.IO.FolderItem nos proporciona el método [Children](http://developer.xojo.com/xojo-io-folderitem$Children) de modo que posteriormente podamos utilizar la estructura de bucle For…Each…In para recorrer cada uno de los elementos disponibles en el iterador.
Así, por ejemplo podremos reflejar en un ListBox todos los archivos visibles disponibles en la carpeta de Documentos mediante el siguiente fragmento de código:
using XOjo.io
dim f as FolderItem = SpecialFolder.Documents
for each i as FolderItem in f.Children
if i.IsFolder = false and i.IsVisible then Listbox1.AddRow i.name
next
Conclusiones
En este artículo hemos tratado los aspectos fundamentales de la clase FolderItem par apuntar a archivos, tanto existentes como los que vaya a crear nuestra aplicación. En todo momento se trata de obtener referencias al sistema de archivos nativo del sistema operativo sobre el que se esté ejecutando nuestra aplicación, permitiéndonos así realizar operaciones comunes (o no tan habituales) sobre los archivos en cuestión.
En próximas entregas veremos como podemos leer y guardar datos en los archivos propiamente dichos, ya se trate en su forma de datos binarios o bien como datos de texto.
Hola Javier, algo que en VB6 lo realizaba bastante simple se me ha complicado en Xojo, y es la apertura y manejo de un archivo local de texto para manejar su información.
Suponer que en un archivo de texto “conexiones.txt” tengo los parámetros de conexión a una base de datos (para no incorporarlo en el código y tener más de una linea de conexión, como está del lado del servidor mantiene la seguridad).
En VB6 es muy simple abrir el archivo (OPEN) y leer sus lineas (INPUT), pero en XOJO WEB se me ha complicado, tienes algún ejemplo que pueda servir?
*el caso presentado aqui no me ayudo ha hacerlo.
Hola Mauricio,
Con FolderItem “apuntas” al archivo con el que quieras trabajar. Posteriormente tienes que utilizar la clase TextInputStream para leer el archivo de texto línea a línea o bien incorporar todo su contenido y asignarlo a la variable deseada. Esta sería la equivalencia de VB6 de lo que necesitas.
Pero es bajo WEB? Porque ahí es donde tengo el problema, pensé que el TextInputStream era para desktop, en ese caso, no me serviría.
Hola Mauricio,
La clase que funciona con todo tipo de proyectos es la que se encuentra bajo el Framework moderno: Xojo.IO.TextInputStream
Hola Javier, quiero obtener de una carpeta (comprobantes) solo los archivos que comiencen con determinado texto (strCI), si quiero obtener todos basta con el GetFolderItem(“comprobantes”) pero el tema es que puedo tener miles de archivos y solo quiero unos pocos que comienzan con un texto, pense que al poner el .Child me dejaría filtrar por el comienzo del texto pero NO me funciona, te mando código debajo por si me podés dar una mano, gracias!
Dim photoFolder, item As FolderItem
Dim strArchivos as String, intPOS as Integer
// para tomar archivos 3333333_1.jpg, 3333333_2.jpg, etc.
strArchivos = “3333333*.jpg”
photoFolder = GetFolderItem(“comprobantes”).Child(strArchivos)
Hola Mauricio,
No puedes utilizar comodines como parte del nombre del texto; es un literal. Para aplicar patrones de búsqueda primero deberías de tomar el nombre de todos los archivos en una matriz, por ejemplo, luego aplicar el filtrado en Xojo sobre dicha matriz (empleando quizá expresiones regulares); y en base a los resultados ya acceder a los archivos coincidentes mediante “child”… es una de las formas.