Dateiverarbeitung in Xamarin.Forms
Die Dateiverarbeitung kann Xamarin.Forms mithilfe von Code in einer .NET Standard-Bibliothek oder mithilfe eingebetteter Ressourcen erreicht werden.
Übersicht
Xamarin.Forms Code wird auf mehreren Plattformen ausgeführt , von denen jeder über ein eigenes Dateisystem verfügt. Früher wurde das Lesen und Schreiben von Dateien einfach mithilfe der nativen Datei-APIs auf der entsprechenden Plattform durchgeführt. Alternativ stellen eingebettete Ressourcen eine einfachere Lösung für das Verteilen von Datendateien mit einer App dar. Mit .NET Standard 2.0 ist es jedoch möglich, Dateizugriffscode in .NET Standard-Bibliotheken freizugeben.
Weitere Informationen zum Verarbeiten von Bilddateien finden Sie unter Working with Images (Arbeiten mit Bildern).
Speichern und Laden von Dateien
Die System.IO
-Klassen können verwendet werden, um auf das Dateisystem jeder Plattform zuzugreifen. Mithilfe der File
-Klasse können Sie Dateien erstellen, löschen und lesen, und mit der Directory
-Klasse können Sie den Inhalt der Verzeichnisse erstellen, löschen oder auflisten. Sie können ebenfalls die Stream
-Unterklassen verwenden, mit denen Sie Dateivorgänge (z.B. die Komprimierung oder die Positionssuche innerhalb einer Datei) besser steuern können.
Eine Textdatei kann mithilfe der File.WriteAllText
-Methode geschrieben werden:
File.WriteAllText(fileName, text);
Eine Textdatei kann mithilfe der File.ReadAllText
-Methode gelesen werden:
string text = File.ReadAllText(fileName);
Darüber hinaus bestimmt die File.Exists
-Methode, ob die angegebene Datei vorhanden ist:
bool doesExist = File.Exists(fileName);
Der Pfad der Datei auf jeder Plattform kann über eine .NET Standard-Bibliothek bestimmt werden, indem ein Wert der Environment.SpecialFolder
-Enumeration als erstes Argument der Environment.GetFolderPath
-Methode verwendet wird. Das Ergebnis kann dann mithilfe der Path.Combine
-Methode mit einem Dateinamen kombiniert werden:
string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp.txt");
Diese Vorgänge werden in der Beispiel-App veranschaulicht, die eine Seite enthält, die Text speichert und lädt:
Laden von als Ressourcen eingebetteten Dateien
Wenn Sie eine Datei in eine .NET Standard-Assembly einbetten möchten, müssen Sie eine Datei erstellen oder hinzufügen und sicherstellen, dass Buildaktion auf „EmbeddedResource“ festgelegt ist.
GetManifestResourceStream
wird verwendet, um über die Ressourcen-ID auf die eingebettete Datei zuzugreifen. Standardmäßig ist die Ressourcen-ID der Dateiname, der dem Standardnamespace für das Projekt vorangestellt ist, in das es eingebettet ist . In diesem Fall ist die Assembly WorkingWithFiles und der Dateiname ist LibTextResource.txt, sodass die Ressourcen-ID lautet 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 ();
}
Die text
-Variable kann anschließend verwendet werden, um den Text darzustellen. Sie können Sie jedoch auch im Code verwenden. Der folgende Screenshot zeigt den in einem Label
Steuerelement gerenderten Text:
Das Laden und Deserialisieren einer XML-Datei ist genauso einfach. Der folgende Code veranschaulicht, wie eine XML-Datei aus einer Ressource geladen und deserialisiert wird und anschließend an ein ListView
-Element gebunden wird, um angezeigt zu werden. Die XML-Datei enthält ein Array von Monkey
-Objekten (die Klasse wird im Beispielcode definiert).
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;
Einbetten in freigegebene Projekte
Freigegebene Projekte können ebenfalls Dateien als eingebettete Ressourcen enthalten. Da der Inhalt eines freigegebenen Projekts jedoch im verweisenden Projekt kompiliert wird, kann das Präfix variieren, das für die Ressourcen-IDs von eingebetteten Dateien verwendet wird. Das bedeutet, dass die Ressourcen-ID für eingebettete Dateien sich je nach Plattform unterscheiden kann.
Für dieses Problem bei freigegebenen Projekten gibt es zwei Lösungsansätze:
- Synchronisieren des Projekts: Bearbeiten Sie die Projekteigenschaften für jede Plattform, damit diese den gleichen Assemblynamen und den Standardnamespace verwenden. Dieser Wert kann dann als Präfix für die Ressourcen-IDs von eingebetteten Dateien im freigegebenen Projekt hartcodiert werden.
- #if-Compilerdirektiven: Verwenden Sie Compilerdirektiven, um das richtige Präfix für die Ressourcen-ID festzulegen, und verwenden Sie diesen Wert, um die richtige Ressourcen-ID dynamisch zu erstellen.
Im Folgenden finden Sie den Code für den zweiten Lösungsansatz. Compilerdirektiven werden verwendet, um das hartcodierte Ressourcenpräfix auszuwählen (das normalerweise dem Standardnamespace für das verweisende Projekt entspricht). Anschließend wird die resourcePrefix
-Variable verwendet, um eine gültige Ressourcen-ID zu erstellen, indem diese mit dem Dateinamen der eingebetteten Ressource verkettet wird.
#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");
Organisieren von Ressourcen
In den oben genannten Beispielen wird davon ausgegangen, dass die Datei in das Stammverzeichnis des Projekts für die .NET Standard-Bibliothek eingebettet ist. In diesem Fall weist die Ressourcen-ID die Form Namespace.Dateiname.Erweiterung auf, z.B. WorkingWithFiles.LibTextResource.txt
oder WorkingWithFiles.iOS.SharedTextResource.txt
.
Es ist möglich, eingebettete Ressourcen in Ordnern zu organisieren. Wenn eine eingebettete Ressource in einem Ordner gespeichert wird, wird der Ordnername Teil der Ressourcen-ID (durch Punkte getrennt). Das Format der Ressourcen-ID entspricht dann Namespace.Ordner.Dateiname.Erweiterung. Wenn Sie die Dateien, die in der Beispiel-App verwendet werden, im Ordner MyFolder speichern würden, wären WorkingWithFiles.MyFolder.LibTextResource.txt
und WorkingWithFiles.iOS.MyFolder.SharedTextResource.txt
die entsprechenden Ressourcen-IDs.
Debuggen von eingebetteten Ressourcen
Manchmal kann nur schwer nachvollzogen werden, warum eine bestimmte Ressource nicht geladen wird. Folgender Code für das Debuggen kann temporär zu einer Anwendung hinzugefügt werden, um zu bestätigen, dass die Ressourcen richtig konfiguriert sind. Dadurch werden alle bekannten Ressourcen, die in die bestimmte Assembly eingebettet sind, im Pad Fehler ausgegeben, um Probleme beim Laden von Ressourcen zu debuggen.
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);
}
Zusammenfassung
In diesem Artikel wurden einfache Dateivorgänge für das Speichern und Laden von Text auf einem Gerät und für das Laden von eingebetteten Ressourcen erläutert. Mit .NET Standard 2.0 ist es möglich, Dateizugriffscode in .NET Standard-Bibliotheken freizugeben.