Subir y descargar archivos en Xojo Web

Subir archivos Web con Xojo

Cuando se trabaja con aplicaciones web es frecuente que se deba de proporcionar la capacidad de subir archivos o bien facilitar la descarga de algún tipo de documento. La clase WebFile se utiliza en dichos casos para crear un tipo de archivo especial que puede procesarse mediante el navegador web, tanto para la subida como para la descarga de archivos. A continuación se proporciona, traducida al castellano, la información publicada originalmente en inglés en el área de desarrolladores de la web de de Xojo y que puede consultarte en este enlace.

Descargar archivos

Para comenzar a descargar un WebiFile has de utilizar el método ShowURL con el objeto de mostrar su URL:

ShowURL(MyWebFile.URL)

En este caso, has de tener en cuenta que MyWebFile ha de mantenerse en el ámbito hasta que finalice la descarga del archivo.

En general, el modo más sencillo de crear un WebFile consiste en crear un FolderItem como punto de partida:

Dim localFile As FolderItem
localFile = GetFolderItem("localfile.txt")
' mTextFile es una propiedad de la página web
' de modo que no se pierda el ámbito
' mientras que se descarga el archivo.
mTextFile = WebFile.Open(localFile)
ShowURL(mTextFile.URL)

El anterior ejemplo carga el archivo desde disco a memoria por cada sesión que inicie la descarga del archivo. Esto derivará rápidamente en el consumo de una gran cantidad de memoria en el servidor web.

Un mejor modo de hacerlo consiste en almacenar una única referencia al WebFile en la clase App global, de modo que no se creen mútiples copias.

Dim localFile As FolderItem
localFile = GetFolderItem("localfile.txt")
' App.TextFile es una propiedad de App
' de modo que no se pierda el ámbito
' mientras que se descarga el archivo
' y se reutiliza en múltiples sesiones.
App.TextFile = WebFile.Open(localFile)
ShowURL(App.TextFile.URL)

La propiedad URL obtiene un URL que es específico a la Sesión al tiempo que se utiliza la misma instancia del archivo WebFile y ahorrando por tanto RAM en el servidor.

Los dos ejemplos anteriores utilizan el método por omisión del evento Open para cargar todo el archivo en memoria. Para ahorrar incluso más memoria en tu servidor web, puedes dejar que el archivo se lea directamente desde disco (en fragmentos de 64 KB) indicando el valor False como segundo parámetro:

Dim localFile As FolderItem
localFile = GetFolderItem("localfile.txt")
' App.TextFile es una propiedad de App
' de modo que no se pierda el ámbito
' mientras que se descarga el archivo.
' El parámetro False carga el archivo desde
' disco en fragmentos de 64K en vez de cargarlo
' por completo todo en memoria de una vez.
mTextFile = WebFile.Open(localFile, False)
ShowURL(App.TextFile.URL)

También puede ser útil un WebFile en memoria, especialmente si estás creando un archivo para su descarga.

Puedes crear un WebFile en memoria y proporcionar su contenido utilizando la propiedad Data:

' mTextFile es una propiedad de la página web
mTextFile = New WebFile
mTextFile.MimeType = "text/plain"
' Asegura que el navegador descargue el archivo en vez
' de intentar mostrarlo.
mTextFile.ForceDownload = True
mTextFile.FileName = "TextFile.txt"
mTextFile.Data = "Hello, world!"
' Esto causa la descarga del archivo
ShowURL(mTextFile.URL)

El anterior ejemplo también demuestra el uso de MimeType para indicar el tipo de datos contenidos en el WebFile y ForceDownload para asegurar que el navegador siempre descargue el archivo. Algunos navegadores intentan mostrar determinados tipos de archivos (como por ejemplo texto, PDF, etc.)

Subir Archivos

Para subir archivos al servidor utilizando una app web puedes utilizar el control WebFileUploader. Este control permite al usuario añadir uno o más archivos a subir. Cuando se inicia la subida (llamando al método Upload), se envían todos los archivos a la app web del servidor desde la cual se pueden procesar en el manejador de evento UploadComplete.

Los archivos subidos con un tamaño superior a 256 KB se escriben directamente a un archivo temporal (en el caso de que se tengan privilegios de escritura). El archivo se mantiene en memoria en el caso de que el archivo temporal no cuente con privilegios de escritura o bien el archivo tenga un tamaño de 256 KB o menos.

Cuando se trabaja con archivos en memoria, conviene tener en cuenta la cantidad RAM máxima disponible en el servidor web.

Una vez se ha subido el archivo, y en el caso de que la carpeta temporal cuente con privilegios de escritura, los archivos en memoria también se copian a disco y se invoca el manejador de evento UploadCompleted.

Si la carpeta temporal no tiene privilegios de escritura, entonces se mantienen en memoria todos los archivos.

En cualquier caso, has de procesar los archivos en el manejador de evento UploadCompleted de modo que puedas guardarlos. Ten en cuenta que los archivos almacenados en la carpeta temporal se borran y los gestionados en memoria se liberan cuando se sale del manejador de evento UploadCompleted.

El siguiente código procesa cada uno de los archivos subidos (que es un WebUploadedFile) en memoria y guarda sus datos a un archivo propiamente dicho en disco utilizando FolderItem y BinaryStream.

Si estás interesado en hacer que tus clases también sean iterables con For Each… Next, puedes leer este artículo

Dim bs As BinaryOutputStream
Dim f As FolderItem
For Each file As WebUploadedFile In Files
f = New FolderItem(file.Name)
Try
bs = BinaryStream.Create(f, True)
bs.Write(file.Data)
bs.Close
Catch e As IOException
' Si se produce un error, salta el archivo
End Try
Next

Sin embargo, es más sencillo y utiliza menos memoria si nos limitamos a invocar el método Save para guardar el archivo en una ubicación permanente:

Dim saveFile As FolderItem
For Each file As WebUploadedFile In Files
saveFile = New FolderItem(file.Name)
Try
file.Save(saveFile)
Catch e As IOException
' Si se produce un error, salta el archivo
Continue
End Try
Next

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *