忘れやすいので備忘録としてメモ。
サンプルには下の処理が含まれています。
- Temporary/Persistent領域確保 (
webkitRequestFileSystem
) - フォルダ作成 (
DirectoryEntry.getDirectory
) - ファイル作成 (
FileEntry.getFile
) - ファイル書込 (
FileWriter
) - ファイル読込 (
FileReader
) - ファイル削除 (
FileEntry.remove
)
※なおサンプルはChromeブラウザで動かすことを前提にしています。webkitなprefixをmozにすればMozilla系でも動くかもしれませんが自分は試してません。
<!DOCTYPE html>
<html>
<meta charset = "utf-8"></meta>
<script type="text/javascript">
window.onload = function() {
// ボタンとかのDOM取得
var read_btn = document.querySelector('#read_btn');
var remove_btn = document.querySelector('#remove_btn');
// FileSystem Instance
var globalFS = null;
// 5MBのTemporary領域を確保してファイル作成
webkitRequestFileSystem(TEMPORARY, 5 * 1024 * 1024 /*5MB*/ , createFile, onErr);
// ちなみにPersistent領域を確保するときはこんな感じ
/*
navigator.webkitPersistentStorage.queryUsageAndQuota(function(usage, quota) {
console.log('usage:' + usage + ', quota:' + quota);
navigator.webkitPersistentStorage.requestQuota(1024 * 1024, function(grantedQuota) {
console.log('grantedQuota:' + grantedQuota);
webkitRequestFileSystem(PERSISTENT, 1024 * 1024, function(fs) {
console.log(fs);
});
});
});
*/
//
// define functions
//
/**
* func for onerror
*/
function onErr(err) {
var msg = '';
switch (err.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR';
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
break;
default:
msg = 'Unknown Error';
break;
}
console.log('Error: ' + msg);
}
/**
* func for initializing FileSystem and creating a file
*/
function createFile(fs) {
globalFS = fs;
console.log('Opened file system: ' + globalFS.name);
// create a directory "mydir"
globalFS.root.getDirectory('mydir', { create: true }, function(dirEntry) {
// create a file "hoge.txt"
/*
* 既にファイルがある場合には内容が上書きされないので注意。
* 上書きした時は一端ファイルを削除してから新規作成すること。
*/
globalFS.root.getFile('mydir/hoge.txt', { create: true }, function(fileEntry) {
console.log('created: ' + fileEntry.fullPath);
// Create a FileWriter object for our FileEntry
fileEntry.createWriter(function(fileWriter) {
var truncated = false;
var data = null;
fileWriter.onwriteend = function(evt) {
console.log('Write completed.');
// 余分なデータ尻をちょん切る。
if(!truncated) {
fileWriter.seek(data.size);
fileWriter.truncate(data.size);
truncated = true;
}
};
fileWriter.onerror = function(evt) {
console.log('Write failed: ' + evt.toString());
};
// create blob data
data = new Blob([ 'helloworld.' ]);
// write data into the file.
fileWriter.write(data);
}, onErr);
}, onErr);
}, onErr);
}
/**
* Read a file
*/
function readFile(){
globalFS.root.getFile('mydir/hoge.txt', {}, function(fileEntry) {
// Get a File object representing the file,
// then use FileReader to read its contents.
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(evt) {
console.log('file contents: ' + this.result);
};
reader.readAsText(file);
}, onErr);
}, onErr);
}
/**
* Remove a file
*/
function removeFile(){
globalFS.root.getFile('mydir/hoge.txt', {}, function(fileEntry) {
// Get a File object representing the file,
// then use FileReader to read its contents.
fileEntry.remove(function() {
console.log('removed: ' + fileEntry.fullPath);
}, onErr);
}, onErr);
}
//
// define onclick actions
//
read_btn.onclick = function() {
readFile();
}
remove_btn.onclick = function() {
removeFile();
}
}
</script>
<button id='read_btn'>readFile</button><br/>
<button id='remove_btn'>removeFile</button><br/>
</html>
上のサンプルはこんな動作をします。
まずブラウザ起動時の動き
1. FileSystemのTemporary領域が確保され、2. Temporary領域にフォルダ
mydir
が作成され、3. Temporary領域にファイル
/mydir/hoge.txt
が作成され、4. 文字列 "
helloworld.
" が書き込まれるこの時点で作成されたファイル /mydir/hoge.txt はChromeブラウザの Peehole から確認することができるし、
ブラウザから
filesystem:http://localhost:8080/temporary/mydir/hoge.txt
にアクセスして確認することもできます。
次にボタン押下時の動き
5. readFileボタンが押下されると mydir/hoge.txt が読み込まれログ表示6. removeFileボタンが押下されると mydir/hoge.txt が削除される
この時点で /mydir/hoge.txt は削除されているので、再びreadFileボタンを押すと
Error: NOT_FOUND_ERR
がログ出力されます。
ログ出力結果
Opened file system: http_localhost_8080:Temporary created: /mydir/hoge.txt Write completed. file contents: helloworld. removed: /mydir/hoge.txt
ちょっとした小技
/dir1/dir2/dir3/myfile.txt
といったフルパスを指定してファイルを作りたい時には、以下のサンプルが役に立つかもしれません。下のコードの
createDirsAndFile()
の処理に注目してください。window.onload = function() {
var filepath = '/dir1/dir2/dir3/myfile.txt';
var dirs = filepath.split('/');
var filename = dirs[dirs.length - 1];
dirs.pop(); // ディレクトリ・リストから "myfile.txt" を除去
webkitRequestFileSystem(TEMPORARY, 5 * 1024 * 1024 /*5MB*/ , function(fs){
createDirsAndFile(fs.root, dirs);
}, onErr);
/**
* ディレクトリを先に準備してからファイルを作成
*/
function createDirsAndFile(fs, dirs) {
// Throw out './' or '/' and move on to prevent something like '/foo/.//bar'.
if (dirs[0] == '.' || dirs[0] == '') {
dirs = dirs.slice(1);
}
if (dirs.length) {
fs.getDirectory(dirs[0], { create: true }, function(dirEntry) {
// 再帰的にディレクトリを作成
createDirsAndFile(dirEntry, dirs.slice(1));
}, onErr);
} else {
// ここでファイル作成
fs.getFile(filename, { create: true }, function(fileEntry){
console.log(fileEntry.fullPath + ' created.');
});
}
}
/**
* func for onerror
*/
function onErr(err) {
var msg = '';
switch (err.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR';
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
break;
default:
msg = 'Unknown Error';
break;
}
console.log('Error: ' + msg);
}
}
createDirsAndFile()
の中では、フォルダが再帰的に作られ、フォルダの階層構造が完成したときに初めてファイルが作成されています。なぜこのような小技が必要になるかというと、階層構造の深いファイルを非同期で次々と作成する際に、フォルダの用意が間に合わずにファイル作成が失敗することが考えられるからです。
0 件のコメント:
コメントを投稿