Utilizzo della compressione in Windows Phone 7.5
Articolo originale pubblicato sabato 14 aprile 2012
NOTA: come sempre, è allegata una versione in Word di questo post per ovviare ai problemi di formattazione del sito. :-)
Come molti di coloro che hanno eseguito attività di sviluppo in Windows Phone già sapranno, non è disponibile un supporto incorporato per la compressione e la decompressione. Molti utenti hanno scelto di utilizzare il progetto SharpCompress su CodePlex e anch'io ho adottato la stessa soluzione per questa operazione. Mancava però un elemento IMPORTANTE, ovvero una documentazione per la decompressione dei file sul telefono. Disponevo già di codice scritto per un'applicazione Windows Form basata sul metodo WriteAllToDirectory per decomprimere un file zip in Windows. Questo metodo tuttavia non esiste nell'assembly per Windows Phone. Non è possibile inoltre limitarsi a fornire il percorso in cui decomprimere i file quando si utilizza l'assembly Windows Phone per SharpCompress. È necessario invece fornire un oggetto flusso.
Questa soluzione ha sostanzialmente funzionato, ma richiede di eseguire alcune operazioni in modo diverso rispetto a quando viene utilizzata nella versione completa di Windows. Di seguito sono elencati alcuni suggerimenti per procedere:
1. Eseguire l'enumerazione sulla raccolta Entry dell'elemento IReader ottenuto dalla factory Reader:
//"sr" is a stream reader object from previous code that contains the byte array of the actual zip file
using (var reader = ReaderFactory.Open(sr))
{
while (reader.MoveToNextEntry())
{
//IsDirectory always returns false in everything I've seen so far
if (!reader.Entry.IsDirectory)
{
//process the entry, described next
}
else
{
//do not know of a scenario where we can end up here
Debug.WriteLine(reader.Entry.FilePath);
}
}
}
2. Creare una o più directory per i file e quindi ottenere un'istanza IsolatedStorageFileStream in cui scrivere:
//IsDirectory always returns false in everything I've seen so far
if (!reader.Entry.IsDirectory)
{
IsolatedStorageFileStream theFile = GetLocalFile(reader.Entry.FilePath);
}
private IsolatedStorageFileStream GetLocalFile(string fullPath)
{
IsolatedStorageFileStream fs = null;
try
{
//get isolated storage so we can create directories and decompress
IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
//trim everything from the last index of /, which is the file
//name, i.e. it will look like folder/folder/folder/filename.txt
string dirPath = fullPath.Substring(0, fullPath.LastIndexOf("/"));
//what's nice is you can create the full folder path in one call
if (!storage.DirectoryExists(dirPath))
storage.CreateDirectory(dirPath);
//now that all the directories exist, create a stream for the
// file – again, cool because you can just give the full path
fs = storage.CreateFile(fullPath);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
return fs;
}
3. Ora che si dispone di un flusso, è possibile scrivere il singolo file per l'utilizzo del metodo WriteEntryTo:
if (!reader.Entry.IsDirectory)
{
IsolatedStorageFileStream theFile = GetLocalFile(reader.Entry.FilePath);
if (theFile != null)
reader.WriteEntryTo(theFile);
}
Mi auguro che queste informazioni possano essere di aiuto. L'assenza di documentazione è stata problematica e mi sono dovuto ingegnare.
Questo è un post di blog localizzato. L'articolo originale è disponibile in Using Compression on Windows Phone 7.5.