Speicher-APIs

Nahezu jeder Aspekt der App-Entwicklung beinhaltet ein Element des Sendens oder Empfangens von Daten. Beginnen Sie mit den Grundlagen und verwenden Sie ein MVC-Framework, um Ihre Anwendung so zu entwerfen und zu implementieren, dass die Daten vollständig von der Ansicht der Anwendung bezüglich dieser Daten getrennt sind (siehe MVC-Architektur).

Sie müssen auch überlegen, wie mit den Daten umgegangen wird, wenn Ihre App offline ist (siehe Offline zuerst). In diesem Dokument werden die Speicheroptionen für das lokale Senden, Empfangen und Speichern von Daten kurz vorgestellt. Der Rest des Dokuments zeigt, wie Sie die File System APIs und Sync File System APIs von Chrome verwenden (siehe auch fileSystem API und syncFileSystem API).

Speicheroptionen

Gepackte Anwendungen verwenden viele verschiedene Mechanismen zum Senden und Empfangen von Daten. Bei externen Daten (Ressourcen, Webseiten) müssen Sie die Content Security Policy (CSP) beachten. Ähnlich wie bei Chrome-Erweiterungen können Sie ursprungsübergreifende XMLHttpRequests verwenden, um mit Remoteservern zu kommunizieren. Sie können externe Seiten auch isolieren, damit der Rest Ihrer Anwendung sicher ist (siehe Externe Webseiten einbetten).

Beim lokalen Speichern von Daten können Sie die Chrome Storage API verwenden, um kleine Mengen an Stringdaten zu speichern, und IndexedDB, um strukturierte Daten zu speichern. Mit IndexedDB können Sie JavaScript-Objekte in einem Objektspeicher speichern und die Indexe des Speichers zum Abfragen von Daten verwenden. Weitere Informationen finden Sie in der Anleitung zur einfachen Todo-Liste von HTML5 Rock. Verwenden Sie für alle anderen Datentypen wie Binärdaten die Filesystem APIs und Sync Filesystem APIs.

Die Filesystem API und Sync Filesystem von Chrome erweitern die HTML5 FileSystem API. Mit der Filesystem API von Chrome können Apps Inhalte in einem Sandbox-Abschnitt des lokalen Dateisystems des Nutzers erstellen, lesen, darin navigieren und schreiben. Beispielsweise kann eine App zum Teilen von Fotos die Filesystem API verwenden, um vom Nutzer ausgewählte Fotos zu lesen und zu schreiben.

Mit der Sync Filesystem API von Chrome können Apps Daten auf Google Drive eines Nutzers speichern und synchronisieren, sodass dieselben Daten auf verschiedenen Clients verfügbar sind. Beispielsweise kann eine cloudgestützte Texteditor-Anwendung neue Textdateien automatisch mit dem Google Drive-Konto eines Nutzers synchronisieren. Wenn der Nutzer den Texteditor in einem neuen Client öffnet, überträgt Google Drive neue Textdateien in diese Instanz des Texteditors.

Chrome Filesystem API verwenden

Dateisystemberechtigung wird hinzugefügt

Wenn Sie die File System API von Chrome verwenden möchten, müssen Sie dem Manifest die Berechtigung „fileSystem“ hinzufügen, damit Sie vom Nutzer die Berechtigung erhalten, persistente Daten zu speichern.

"permissions": [
  "...",
  "fileSystem"
]

Nutzeroptionen für die Auswahl von Dateien

Nutzer erwarten, dass sie Dateien wie gewohnt auswählen. Sie erwarten mindestens eine Schaltfläche "Datei auswählen" und eine Standard-Dateiauswahl. Wenn in Ihrer App Dateihandarbeit intensiv erforderlich ist, sollten Sie auch Drag-and-drop implementieren (siehe unten und auch Natives HTML5-Drag-and-drop).

Pfad eines fileEntrys ermitteln

Rufen Sie getDisplayPath() auf, um den vollständigen Pfad der vom Nutzer ausgewählten Datei (fileEntry) abzurufen:

function displayPath(fileEntry) {
  chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
    console.log(path)
  });
}

Drag-and-drop implementieren

Wenn Sie eine Drag-and-drop-Auswahl implementieren müssen, ist der Drag-and-drop-Dateicontroller (dnd.js) aus dem Beispiel filesystem-access ein guter Ausgangspunkt. Der Controller erstellt per Drag-and-drop einen Dateieintrag aus einem DataTransferItem. In diesem Beispiel ist fileEntry auf das erste verworfene Element festgelegt.

var dnd = new DnDFileController('body', function(data) {
  var fileEntry = data.items[0].webkitGetAsEntry();
  displayPath(fileEntry);
});

Datei lesen

Mit dem folgenden Code wird die Datei (schreibgeschützt) geöffnet und mithilfe eines FileReader-Objekts als Text gelesen. Wenn die Datei nicht vorhanden ist, wird ein Fehler ausgegeben.

var chosenFileEntry = null;

chooseFileButton.addEventListener('click', function(e) {
  chrome.fileSystem.chooseEntry({type: 'openFile'}, function(readOnlyEntry) {

    readOnlyEntry.file(function(file) {
      var reader = new FileReader();

      reader.onerror = errorHandler;
      reader.onloadend = function(e) {
        console.log(e.target.result);
      };

      reader.readAsText(file);
    });
    });
});

Schreiben einer Datei

Die beiden häufigsten Anwendungsfälle für das Schreiben einer Datei sind „Speichern“ und „Speichern unter“. Mit dem folgenden Code wird ein writableEntry aus dem schreibgeschützten chosenFileEntry erstellt und die ausgewählte Datei darin geschrieben.

 chrome.fileSystem.getWritableEntry(chosenFileEntry, function(writableFileEntry) {
    writableFileEntry.createWriter(function(writer) {
      writer.onerror = errorHandler;
      writer.onwriteend = callback;

    chosenFileEntry.file(function(file) {
      writer.write(file);
    });
  }, errorHandler);
});

Mit dem folgenden Code wird eine neue Datei mit der Funktion "Speichern unter" erstellt und das neue Blob mit der Methode writer.write() in die Datei geschrieben.

chrome.fileSystem.chooseEntry({type: 'saveFile'}, function(writableFileEntry) {
    writableFileEntry.createWriter(function(writer) {
      writer.onerror = errorHandler;
      writer.onwriteend = function(e) {
        console.log('write complete');
      };
      writer.write(new Blob(['1234567890'], {type: 'text/plain'}));
    }, errorHandler);
});

Über die Chrome Sync Filesystem API

Mithilfe des synchronisierbaren Dateispeichers können zurückgegebene Datenobjekte auf dieselbe Weise wie lokale Offlinedateisysteme in der FileSystem API verarbeitet werden, aber mit der zusätzlichen (und automatischen) Synchronisierung dieser Daten mit Google Drive.

Berechtigung zum Synchronisieren des Dateisystems wird hinzugefügt

Um die Sync Filesystem API von Chrome zu verwenden, müssen Sie dem Manifest die Berechtigung „syncFileSystem“ hinzufügen, damit Sie die Berechtigung vom Nutzer zum Speichern und Synchronisieren persistenter Daten erhalten können.

"permissions": [
  "...",
  "syncFileSystem"
]

Synchronisierbaren Dateispeicher wird initiiert

Um den synchronisierbaren Dateispeicher in Ihrer App zu starten, rufen Sie einfach syncFileSystem.requestFileSystem auf. Diese Methode gibt ein synchronisierbares Dateisystem zurück, das von Google Drive gesichert wird. Beispiel:

chrome.syncFileSystem.requestFileSystem(function (fs) {
   // FileSystem API should just work on the returned 'fs'.
   fs.root.getFile('test.txt', {create:true}, getEntryCallback, errorCallback);
});

Informationen zum Dateisynchronisierungsstatus

Verwenden Sie syncFileSystem.getFileStatus, um den Synchronisierungsstatus für eine aktuelle Datei abzurufen:

chrome.syncFileSystem.getFileStatus(entry, function(status) {...});

Für die Dateisynchronisierungsstatus sind folgende Werte möglich: 'synced', 'pending' oder 'conflicting'. „Synchronisiert“ bedeutet, dass die Datei vollständig synchronisiert ist. Es gibt keine ausstehenden lokalen Änderungen, die nicht mit Google Drive synchronisiert wurden. Es kann jedoch ausstehende Änderungen auf Google Drive-Seite geben, die noch nicht abgerufen wurden.

„Ausstehend“ bedeutet, dass die Datei ausstehende Änderungen enthält, die noch nicht mit Google Drive synchronisiert wurden. Wenn die Anwendung online ausgeführt wird, werden lokale Änderungen (fast) sofort mit Google Drive synchronisiert und das Ereignis syncFileSystem.onFileStatusChanged mit dem Status 'synced' ausgelöst. Weitere Informationen finden Sie unten.

syncFileSystem.onFileStatusChanged wird ausgelöst, wenn sich der Status einer Datei zu 'conflicting' ändert. "In Konflikt stehend" bedeutet, dass sowohl beim lokalen Speicher als auch in Google Drive widersprüchliche Änderungen vorliegen. Eine Datei kann diesen Status nur dann haben, wenn die Richtlinie zur Konfliktlösung auf 'manual' gesetzt ist. Die Standardrichtlinie ist 'last_write_win'. Konflikte werden automatisch durch die einfache Richtlinie „Last-Write-Win“ gelöst. Die Richtlinie zur Konfliktlösung des Systems kann mit syncFileSystem.setConflictResolutionPolicy geändert werden.

Wenn die Richtlinie zur Konfliktlösung auf 'manual' gesetzt ist und eine Datei den Status 'conflicting' hat, kann die Anwendung die Datei trotzdem als lokale Offlinedatei lesen und schreiben. Die Änderungen werden jedoch nicht synchronisiert und die Datei von Remote-Änderungen auf anderen Clients getrennt, bis der Konflikt behoben ist. Am einfachsten lösen Sie einen Konflikt, indem Sie die lokale Version der Datei löschen oder umbenennen. Dadurch wird die Synchronisierung der Remote-Version erzwungen, der Konfliktstatus aufgelöst und das Ereignis onFileStatusChanged mit dem Status 'synced' ausgelöst.

Warten auf Änderungen im Synchronisierungsstatus

Das Ereignis syncFileSystem.onFileStatusChanged wird ausgelöst, wenn sich der Synchronisierungsstatus einer Datei ändert. Angenommen, eine Datei weist ausstehende Änderungen auf und hat den Status "Ausstehend". Möglicherweise war die Anwendung offline, sodass die Änderung gleich synchronisiert wird. Wenn der Synchronisierungsdienst die ausstehende lokale Änderung erkennt und die Änderung in Google Drive hochlädt, löst der Dienst das Ereignis onFileStatusChanged mit den folgenden Werten aus: { fileEntry:a fileEntry for the file, status: 'synced', action: 'updated', direction: 'local_to_remote' }.

In ähnlicher Weise kann der Synchronisierungsdienst unabhängig von den lokalen Aktivitäten Remote-Änderungen erkennen, die von einem anderen Client vorgenommen wurden, und die Änderungen aus Google Drive in den lokalen Speicher herunterladen. Wenn die Remote-Änderung das Hinzufügen einer neuen Datei betraf, wird ein Ereignis mit den folgenden Werten ausgelöst: { fileEntry: a fileEntry for the file, status: 'synced', action: 'added', direction: 'remote_to_local' }.

Wenn sowohl auf der lokalen als auch auf der Remote-Seite in Konflikt stehende Änderungen für dieselbe Datei vorliegen und die Richtlinie zur Konfliktlösung auf 'manual' gesetzt ist, wird der Dateistatus in conflicting geändert, vom Synchronisierungsdienst getrennt und erst synchronisiert, wenn der Konflikt behoben ist. In diesem Fall wird ein Ereignis mit den folgenden Werten ausgelöst: { fileEntry: a fileEntry for the file, status: 'conflicting', action: null, direction: null }.

Sie können diesem Ereignis einen Listener hinzufügen, der auf Statusänderungen reagiert. Die App Chrome Music Player wartet beispielsweise auf neue Musik, die aus Google Drive synchronisiert, aber noch nicht in den lokalen Speicher des Nutzers auf einem bestimmten Client importiert wurde. Jede gefundene Musik wird mit diesem Client synchronisiert:

chrome.syncFileSystem.onFileStatusChanged.addListener(function(fileInfo) {
  if (fileInfo.status === 'synced') {
    if (fileInfo.direction === 'remote_to_local') {
      if (fileInfo.action === 'added') {
        db.add(fileInfo.fileEntry);
      } else if (fileInfo.action === 'deleted') {
        db.remove(fileInfo.fileEntry);
      }
    }
  }
});

API-Nutzung prüfen

Fragen Sie das lokale, in der Sandbox ausgeführte Verzeichnis der Anwendung oder die von syncFileSystem.getUsageAndQuota zurückgegebenen Nutzungsbyte ab, um die von der API verwendete Datenmenge zu prüfen:

chrome.syncFileSystem.getUsageAndQuota(fileSystem, function (storageInfo) {
   updateUsageInfo(storageInfo.usageBytes);
   updateQuotaInfo(storageInfo.quotaBytes);
});

Sie können sich auch den Speicher des Synchronisierungs-Back-End-Dienstes des Nutzers in Google Drive ansehen. Synchronisierte Dateien werden im verborgenen Google Drive-Ordner Chrome Syncable FileSystem gespeichert. Der Ordner wird nicht in der Liste „Meine Ablage“ angezeigt, Sie können ihn aber aufrufen, indem Sie im Suchfeld nach dem Ordnernamen suchen. Beachten Sie, dass das Layout des Remote-Ordners nicht garantiert abwärtskompatibel zwischen Releases ist.