これを使えば開発者はローカル/リモートのファイルストレージを一つのコードで利用することができるのだ。
これを利用すれば、アプリをオフラインで使っているときはアプリが扱うデータはローカルに保存され、オンラインになると自動的にリモート(Google Drive)と同期させることができるようになる。アプリの利便性が向上すること間違いなし。なんと素晴らしいAPIだろうか。
では早速サンプルコードを見てみよう。
このサンプルアプリも例によって packaged apps プロジェクトとして作ってある。
ファイル構成:
app.js
background.js
calculator-128.png
calculator-16.png
index.html
manifest.json
重要なのは太字の箇所。
まずはmanifest.jsonから見てみよう。
{ "name": "syncFilesystem sample App", "description": "Sample app using the Chrome SyncFilesystem API.", "version": "0.1", "app": { "background": { "scripts": ["background.js"] } }, "icons": { "16": "calculator-16.png", "128": "calculator-128.png" }, "permissions": [ "syncFileSystem" ] }
permissions に "syncFileSystem" を設定しているところが重要。
次に index.html
<!DOCTYPE html> <html ng-app ng-csp> <head> <meta charset='utf-8'> </head> <body> <button id="create_btn">Create a file / append data</button> <button id="read_btn">Read a file</button> <button id="remove_btn">Remove a file</button> <pre id="result"></pre> <script src="app.js"></script> </body> </html>
ファイル作成(ファイル書込)ボタン、ファイル読込ボタン、ファイル削除ボタンの3つのボタンが設置されている。
id="result"なdivには読み込んだファイル内容を表示する。
いよいよお待ちかねの app.js
document.getElementById('create_btn').onclick = function() { chrome.syncFileSystem.requestFileSystem(function (fs) { fs.root.getFile('test.txt', {create:true}, function(fileEntry){ fileEntry.createWriter(function(fileWriter) { fileWriter.onwriteend = function(e) { console.log('fileWriter.onWriteEnd.'); console.log('fileEntry.fullPath:' + fileEntry.fullPath); }; fileWriter.onerror = function(e) { console.log('fileWriter.onError:' + e.toString()); }; // 内容にテキトーな文字列(日付)を「追記」 fileWriter.seek(fileWriter.length); // この行を削除すれば「新規書込モード」になる var blob = new window.Blob([new Date() + '\n']); fileWriter.write(blob); }, function(error){ console.log('fileEntry.createWriter error:' + error.code); }); }, function(error){ console.log('syncFileSystem.getFile error:' + error.code); } ); }); }; document.getElementById('read_btn').onclick = function() { chrome.syncFileSystem.requestFileSystem(function (fs) { fs.root.getFile('test.txt', {create:false}, function(fileEntry){ fileEntry.file(function(file){ // FileReaderを生成 var reader = new FileReader(); // ファイルロード完了時処理 reader.onloadend = function(e){ var txtArea = document.getElementById('result'); txtArea.innerText = this.result; }; // FileReaderでテキストを読み込み reader.readAsText(file); }, function(error){ console.log('fileEntry.file error:' + error.code); } ); }, function(error){ console.log('fileEntry.getFile error:' + error.code); } ); }); }; document.getElementById('remove_btn').onclick = function() { chrome.syncFileSystem.requestFileSystem(function (fs) { fs.root.getFile('test.txt', {create:false}, function(fileEntry){ fileEntry.remove(function(){ console.log('a file removed.'); }, function(error){ console.log('fileEntry.remove error:' + error.code); } ); }, function(error){ console.log('fileEntry.getFile error:' + error.code); } ); }); };
「新規作成(書込)」、「読込」、「削除」の全ての処理で共通なのは、chrome.syncFileSystem.requestFileSystem(function (fs) {...} 内で fs.root.getFile() するところ。
後は取得した fileEntry で FileWriter を取得して新規作成/書込を行うか、FileReaderを生成して読込を行うか、fileEntry.remove() でファイル削除を行うかすれば良いだけ。
SyncFileSystem API のインターフェースは基本的に FileSystem APIと変わらない。
ちなみにこのサンプルアプリで生成されたデータはどこに保存されているかというと、
まずChromeにGoogleアカウントでログインしていない場合は、
C:\Users\<USERNAME>\AppData\Local\Google\Chrome\User Data\Default\Storage\ext\<APP_ID>\def\File System\000\s\00\00000002
に保存されていて、
ログインしている場合には、
上記のローカルパスとGoogleDriveの両方にファイルが自動保存されている。GoogleDrive上でのパスは、
/Chrome Syncable FileSystem/<APP_ID>/test.txt
となる。
サンプルが動かないとき
このサンプルを試すにはChromeにログインする必要がある。ログインしていないと下のようなエラーメッセージが出てうまく動かないので注意が必要だ。syncFileSystem.requestFileSystem: Sync: authentication failed. at chrome-extension://fsdfdafsdfdsfsafdsfaadfadsfsadfdsaf/app.js:8:23
作った本人も忘れた頃にハマりました。
参考
Manage Data - Google Chrome
ブラウザーにファイルを残せるFile system APIの使い方 - ASCIIネット
Exploring the FileSystem APIs - HTML5 Rocks
関連エントリ
AngularJSを使って画面遷移、バリデーションなど。
JS用MVCフレームワーク「AngularJS」を使ってChrome Packaged Apps【基本編】
【Chrome】Packaged Apps アプリをHelloWorld【Google】
スマホOSの主導権争いの行方