これを使えば開発者はローカル/リモートのファイルストレージを一つのコードで利用することができるのだ。
これを利用すれば、アプリをオフラインで使っているときはアプリが扱うデータはローカルに保存され、オンラインになると自動的にリモート(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の主導権争いの行方