Gestione dei file in Xamarin.Forms
La gestione dei file con Xamarin.Forms può essere ottenuta usando il codice in una libreria .NET Standard o usando risorse incorporate.
Panoramica
Xamarin.Forms il codice viene eseguito su più piattaforme, ognuna delle quali ha un proprio file system. In passato, questo comportava che la lettura e la scrittura di file risultasse molto semplice con le API di file native in ogni piattaforma. In alternativa, le risorse incorporate sono una soluzione più semplice per distribuire file di dati con un'app. Con .NET Standard 2.0, tuttavia, è possibile condividere il codice di accesso ai file nelle librerie .NET Standard.
Per informazioni sulla gestione dei file di immagine, vedere la pagina Uso delle immagini.
Salvataggio e caricamento di file
In ogni piattaforma è possibile usare le classi System.IO
per accedere al file system. La classe File
consente di creare, eliminare e leggere i file e la classe Directory
consente di creare, eliminare o enumerare il contenuto delle directory. È anche possibile usare le sottoclassi Stream
che possono offrire un livello di controllo più elevato sulle operazioni sui file, ad esempio la compressione o la ricerca di una posizione all'interno di un file.
È possibile scrivere un file di testo usando il metodo File.WriteAllText
:
File.WriteAllText(fileName, text);
È possibile leggere un file di testo usando il metodo File.ReadAllText
:
string text = File.ReadAllText(fileName);
Il metodo File.Exists
, inoltre, determina se il file specificato esiste:
bool doesExist = File.Exists(fileName);
Il percorso del file in ogni piattaforma può essere determinato da una libreria .NET Standard usando un valore dell'enumerazione Environment.SpecialFolder
come primo argomento per il metodo Environment.GetFolderPath
. Questo può quindi essere combinato con un nome di file con il metodo Path.Combine
:
string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp.txt");
Queste operazioni sono illustrate nell'app di esempio che include una pagina che salva e carica il testo:
Caricamento di file incorporati come risorse
Per incorporare un file in un assembly .NET Standard, creare o aggiungere un file e assicurarsi di selezionare Azione compilazione: Risorsa incorporata.
GetManifestResourceStream
viene usato per accedere al file incorporato usando il relativo ID risorsa. Per impostazione predefinita, l'ID risorsa è il nome file preceduto dallo spazio dei nomi predefinito per il progetto in cui è incorporato. In questo caso, l'assembly è WorkingWithFiles e il nome file è LibTextResource.txt, quindi l'ID risorsa è WorkingWithFiles.LibTextResource.txt
.
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(LoadResourceText)).Assembly;
Stream stream = assembly.GetManifestResourceStream("WorkingWithFiles.LibTextResource.txt");
string text = "";
using (var reader = new System.IO.StreamReader (stream))
{
text = reader.ReadToEnd ();
}
La variabile text
può quindi essere usata per visualizzare il testo oppure è possibile usarla nel codice. Lo screenshot seguente mostra il testo di cui è stato eseguito il rendering in un Label
controllo :
Il caricamento e la deserializzazione di un file XML è ugualmente semplice. Il codice seguente illustra un file XML che viene caricato e deserializzato da una risorsa e quindi associato a un elemento ListView
per la visualizzazione. Il file XML contiene una matrice di oggetti Monkey
(la classe è definita nel codice di esempio).
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(LoadResourceText)).Assembly;
Stream stream = assembly.GetManifestResourceStream("WorkingWithFiles.LibXmlResource.xml");
List<Monkey> monkeys;
using (var reader = new System.IO.StreamReader (stream)) {
var serializer = new XmlSerializer(typeof(List<Monkey>));
monkeys = (List<Monkey>)serializer.Deserialize(reader);
}
var listView = new ListView ();
listView.ItemsSource = monkeys;
Incorporamento in progetti condivisi
I progetti condivisi possono anche contenere file come risorse incorporate. Tuttavia, poiché il contenuto di un progetto condiviso viene compilato nei progetti di riferimento, il prefisso usato per gli ID risorsa del file incorporato può cambiare. Ciò significa che l'ID risorsa per ogni file incorporato può essere diverso per ogni piattaforma.
Nei progetti condivisi questo problema ha due soluzioni:
- Sincronizzare i progetti: modificare le proprietà del progetto per ogni piattaforma in modo da usare lo stesso nome di assembly e spazio dei nomi predefinito. Questo valore può quindi essere impostato come "hardcoded" e usato come prefisso per gli ID della risorsa incorporata nel progetto condiviso.
- Direttive #if del compilatore: usare le direttive del compilatore per impostare il prefisso di ID risorsa corretto e usare questo valore per costruire in modo dinamico l'ID risorsa corretto.
Il codice che illustra la seconda opzione è riportato di seguito. Le direttive del compilatore vengono usate per selezionare il prefisso hardcoded della risorsa che in genere corrisponde allo spazio dei nomi predefinito per il progetto di riferimento. Viene quindi usata la variabile resourcePrefix
per creare un ID risorsa valido concatenandolo con il nome file della risorsa incorporata.
#if __IOS__
var resourcePrefix = "WorkingWithFiles.iOS.";
#endif
#if __ANDROID__
var resourcePrefix = "WorkingWithFiles.Droid.";
#endif
Debug.WriteLine("Using this resource prefix: " + resourcePrefix);
// note that the prefix includes the trailing period '.' that is required
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(SharedPage)).Assembly;
Stream stream = assembly.GetManifestResourceStream
(resourcePrefix + "SharedTextResource.txt");
Organizzazione delle risorse
Negli esempi precedenti si presuppone che il file sia incorporato nella radice del progetto libreria .NET Standard. In questo caso, il formato dell'ID risorsa è Namespace.Filename.Extension, ad esempio WorkingWithFiles.LibTextResource.txt
e WorkingWithFiles.iOS.SharedTextResource.txt
.
È possibile organizzare le risorse incorporate in cartelle. Quando una risorsa incorporata viene inserita in una cartella, il nome di quest'ultima diventa parte dell'ID della risorsa (separato da punti), in modo tale che il formato dell'ID della risorsa diventa Namespace.Folder.Filename.Extension. Se si inseriscono i file usati nell'app di esempio in una cartella MyFolder, gli ID risorsa corrispondenti saranno WorkingWithFiles.MyFolder.LibTextResource.txt
e WorkingWithFiles.iOS.MyFolder.SharedTextResource.txt
.
Debug delle risorse incorporate
A volte è difficile comprendere il motivo per cui una determinata risorsa non viene caricata. Per verificare che le risorse siano configurate correttamente è possibile aggiungere temporaneamente a un'applicazione il codice di debug seguente. Tutte le risorse note incorporate nell'assembly specificato verranno visualizzate nel riquadro Errori per facilitare il debug dei problemi di caricamento delle risorse.
using System.Reflection;
// ...
// use for debugging, not in released app code!
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(SharedPage)).Assembly;
foreach (var res in assembly.GetManifestResourceNames()) {
System.Diagnostics.Debug.WriteLine("found resource: " + res);
}
Riepilogo
Questo articolo ha illustrato semplici operazioni su file per il salvataggio e il caricamento di testo nel dispositivo e per il caricamento delle risorse incorporate. Con .NET Standard 2.0 è possibile condividere il codice di accesso ai file nelle librerie .NET Standard.
Collegamenti correlati
- Xamarin.Forms Campioni
- Working with the File System in Xamarin.iOS (Uso del file system in Xamarin.iOS)