
Descargar un fichero .zip y abrirlo en memoria con Xamarin.
Cuando tenemos que descargar muchos datos en nuestra aplicación, el formato JSON no siempre es la mejor opción.
En mi caso, tenia un JSON que ocupaba 22Mb, ya que muchos caracteres estaban escapados por el tema de la codificación.
Al comprimir en .zip, el tamaño del archivo ha bajado para 1,9Mb. Como se puede ver, es una reducción considerable.
Lo que vamos hacer ahora con Xamarin, es leer este archivo .Zip, descomprimirlo y por último deserializar todos los ficheros dentro.
Los pasos a seguir son:
1) Instalar el paquete de nuget: System.IO.Compression;
2) El siguiente caso, es hacer la petición a nuestro servidor para obtener el archivo.
String url = Url donde se encuentra el fichero
HttpClient client = new HttpClient();
Byte[] content = await client.GetByteArrayAsync(url);
3) Verificamos que no es nula la petición y transformamos los datos en Stream.
if (content == null)
{
// tratar el error
return null;
}
Stream data = new MemoryStream(content);
4) Creamos una variable donde vamos a manejar todos los ficheros dentro del Zip.
Stream myFile;
5) Usamos la función ZipArchive para leer el fichero directamente.
ZipArchive archive = new ZipArchive(data);
6) Por ultimo, recogemos todos los ficheros del .Zip y tratamos los datos.
if (archive == null)
{
// tratar el error
return null;
}
foreach (ZipArchiveEntry file in archive.Entries)
{
// Verificamos el nombre del archivo para tratar cada estructura de una forma distinta.
if (file.FullName== "mi_archivo_1.json")
{
//Abre y retorna un stream
myFile = file.Open();
StreamReader reader = new StreamReader(myFile);
string myText = reader.ReadToEnd();
//Usamos newtonsoft para deserializar el JSON.
MyModel mymodel = JsonConvert.DeserializeObject(text);
}
if (file.FullName== "mi_archivo_2.json")
{
//Abre y retorna un stream
myFile = file.Open();
StreamReader reader = new StreamReader(myFile);
string myText = reader.ReadToEnd();
//Usamos newtonsoft para deserializar el JSON.
MyModel2 mymodel2 = JsonConvert.DeserializeObject(text);
}
}
Actualización del útimo paso:
6)[Actualizado] Tal como indica Xleon en los comentarios, no es necesario convertir el stream en una cadena de texto. Podemos hacer el último paso de la siguiente forma:
if (archive == null)
{
// tratar el error
return null;
}
JsonSerializer serializer = new JsonSerializer();
foreach (ZipArchiveEntry file in archive.Entries)
{
// Verificamos el nombre del archivo para tratar cada estructura de una forma distinta.
if (file.FullName== "mi_archivo_1.json")
{
//Abre y retorna un stream
myFile = file.Open();
StreamReader reader = new StreamReader(myFile);
//Cambio aplicado para optimizar el proceso y evitar el uso de memoria de forma innecesaria. Gracias a Xleon
MyModel myModel = (MyModel)serializer.Deserialize(reader, typeof(MyModel));
}
if (file.FullName== "mi_archivo_2.json")
{
//Abre y retorna un stream
myFile = file.Open();
StreamReader reader = new StreamReader(myFile);
//Cambio aplicado para optimizar el proceso y evitar el uso de memoria de forma innecesaria. Gracias a Xleon
MyModel2 myModel2 = (MyModel2)serializer.Deserialize(reader, typeof(MyModel2));
}
}
Con esto es todo, hasta la próxima.