HTML5文件系统API和资料整理
来着火狐开发网络的官方文档:点我打开 ;
W3C的官方文档: 点我打开 ;
园友的博客: 点我打开;
浏览器兼容性, 好了就chrome支持, 我刚刚更新的火狐37也不支持, nice, 太nice了:
如果我们在http://localhost/下使用文件系统api创建了虚拟文件, 那么通过一下地址可以访问文件系统:filesystem:http://localhos1/persistent/ ;
如果没有文件系统没有本地文件, 那么应该是一个错误界面:
就chrome支持本地文件系统, 所以兼容完全不用管那么多了, 我们先通过 requestFileSystem获取文件句柄, 第一个参数为临时文件系统,还是永久文件系统; 第二个参数为请求的空间大小; 第三个是回调函数;
//window.TEMPORARY 是 0 , window.PERSISTENT是1; storeType = storeType === 0 ? window.TEMPORARY : window.PERSISTENT; window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; window.requestFileSystem(storeType, 5 * 1024 * 1024, function (fs) { console.log(fs);//文件系统根目录句柄(root); }, errorHandler);
上面回调函数会返回一个参数fs,这个参数“fs”很重要, fs下面有很多方法, 主要是操作文件或者目录:
getDirectory是在对象上面的方法, 这个主要是处理目录,比如打开目录, 或者新建目录:
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
path | DOMString |
✘ | ✘ | Either an absolute path or a relative path from this DirectoryEntry to the directory to be looked up or created. It is an error to attempt to create a directory whose immediate parent does not yet exist. |
options |
|
✘ | ✔ |
|
successCallback |
|
✘ | ✔ | A callback that is called to return the DirectoryEntry selected or created. |
errorCallback |
|
✘ | ✔ | A callback that is called when errors happen. |
getFile这个是获取文件, 作用是打开文件或者新建文件;
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
path | DOMString |
✘ | ✘ | Either an absolute path or a relative path from this DirectoryEntry to the file to be looked up or created. It is an error to attempt to create a file whose immediate parent does not yet exist. |
options |
|
✘ | ✔ |
|
successCallback |
|
✘ | ✔ | A callback that is called to return the File selected or created. |
errorCallback |
|
✘ | ✔ | A callback that is called when errors happen. |
通过上面的方法,我们就获取到了文件句柄啦, 那么可以通过FileReader对象读取文件, 通过Blob对象创建二进制流, 把数据保存到文件,以及FileWriter也很重要;
FileReader的API;
Blob的API;
FileWriter的API;
通过 getFile 可以获取到fileEntry对象,fileEntry就是这个文件的对象,我们可以操作文件了哦, 方法如下:createWriter , file :
通过createWriter这个的回调参数我们可以得到操作这个二进制文件的方法:
createWriter
-
Creates a new FileWriter associated with the file that this
FileEntry
represents.Parameter Type Nullable Optional Description successCallback FileWriterCallback
✘ ✘ A callback that is called with the new FileWriter. errorCallback ErrorCallback
✘ ✔ A callback that is called when errors happen. Return type:void
- 通过file方法,我们就获取到了文件数据, 这个file就是 file类型的input 中获取到的文件对象:
file
-
Returns a File that represents the current state of the file that this
FileEntry
represents.Parameter Type Nullable Optional Description successCallback FileCallback
✘ ✘ A callback that is called with the File. errorCallback ErrorCallback
✘ ✔ A callback that is called when errors happen. Return type:void
在文件上提供了remove在文件夹上提供了remove和removeRecursively方法;以及moveto方法copyto的方法;但是没有提供rename,所以我们要自己通过moveto方法写一个rename方法;我通过API封装了一个在本地文件系统中文本文件的读写的小库,经测试, 可以新建文件文件夹,复制文件文件夹,读写text的文本文件(prependText,appendText),重写文件, 重命名文件等基本的功能, 可以作为学习的参考哇:var FS = (function () { /** * FF火狐不支持fileSystem ;http://dev.w3.org/2009/dap/file-system/file-dir-sys.html * * */ var _FS = function() {}; var p = _FS.prototype; //init应该创建一个文件系统,可以是临时或者是永久的; p.init = function (storeType) { var $df = $.Deferred(); //window.TEMPORARY 是 0 , window.PERSISTENT是1; storeType = storeType === 0 ? window.TEMPORARY : window.PERSISTENT; window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; window.requestFileSystem(storeType, 5 * 1024 * 1024, function (fs) { //把这个fs句柄绑定到实例的原型上; p.fs = fs; $df.resolve(p); }, errorHandler); return $df; }; /** * @param "hehe/xxx/dir" 新建一个目录,如果目录存在就把目录打开; * @return Deferred , @param dirEntry, @this_prototpe; * */ p.createDir = function (folders) { var $df = $.Deferred(); if(folders === "/" || folders === "./") { $df.resolve(p.fs.root, p); return $df; }; /** * @param 文件夹的数组["hehe","wawa", "lala", "dudu"] * @param 要创建文件的目录 * */ var createDir = function (folders, entry) { entry.getDirectory(folders.shift(), {create: true}, function (dirEntry) { //如果folder还有目录就调用自己,继续新建目录; 否则就resolve; var testLength = folders.length; if (testLength) { createDir(folders, dirEntry); } else { $df.resolve(dirEntry, p); } ; }, errorHandler); }; createDir(folders.split("/"), p.fs.root); return $df; }; /** * @desc 新建文件; * @param fileName 要新建的文件名字; * @param entry 文件目录入口 * @return 延迟对象, 该延迟对象的实际参数为 @文件句柄, @这个实例的原型; * */ p.createFile = function (fileName, entry) { $df = $.Deferred(); try { ; //如果文件存在就直接返回存在的文件; entry.getFile(fileName, {create: false, exclusive: true}, function (fileEntry) { $df.resolve(fileEntry, p); }, function (ex) { if (ex.name === "NotFoundError") { //否则就新建文件并返回; entry.getFile(fileName, { create: true, exclusive: true }, function (fileEntry) { $df.resolve(fileEntry, p); }, errorHandler); } else { alert("文件创建错误!"); } ; }); } catch (ex) { alert("文件打开或者创建错误!"); } ; return $df; }; /** * @desc 打开文件 * @param fileName 要新建的文件名字; * @param entry 文件目录入口 * @return 延迟对象, 该延迟对象的实际参数为 @文件句柄, @这个实例的原型; * */ p.getFile = function (fileName, entry) { $df = $.Deferred(); entry.getFile(fileName, { create: false, exclusive: true }, function (fileEntry) { $df.resolve(fileEntry, p); }, errorHandler); return $df; }; /** * @desc 对文件进行重写; * @param text 要写入的文本数据; * @param fileEntry 文件的句柄; * @return 延迟对象,参数为写入的text文本; * */ p.writeText = function(text, fileEntry) { $df = $.Deferred(); fileEntry.createWriter(function (fileWriter) { fileEntry.file(function(file){ fileWriter.onwriteend = function(){ this.truncate(this.position); $df.resolve(text); }; //chrome,ff中BlobBuilder已经不支持了; fileWriter.write(new Blob([text], { type: "text/plain" })); }); }, errorHandler); return $df; }; /** * @desc 在文件最前头添加text数据; * @param text 要写入的文本数据; * @param fileEntry 文件的句柄; * @return 延迟对象,参数为写入的text文本; * */ p .prePendText = function (text, fileEntry) { $df = $.Deferred(); fileEntry.createWriter(function (fileWriter) { fileEntry.file(function(file){ var reader = new FileReader(file); reader.onloadend = function (e) { //webkit的BlobBuilder已经不支持了; fileWriter.write(new Blob([text+this.result], { type: "text/plain" })); $df.resolve(text); }; reader.readAsText(file); }); }, errorHandler); return $df; }; /** * @desc 在文件末尾添加text; * @param text 要写入的文本数据; * @param fileEntry 文件的句柄; * @return 延迟对象,参数为写入的text文本; * */ p.appendText = function(text, fileEntry) { $df = $.Deferred(); fileEntry.createWriter(function (fileWriter) { //我们可以通过fileWrite对文件进行写入, 也可以通过file方法先获取到file对象, 然后通过FileReader对文件进行写入; fileWriter.seek(fileWriter.length); fileWriter.write( new Blob([text]), {type : "text/plasin"}); fileWriter.onwriteend = function() { $df.resolve(text); } /* fileEntry.file(function(file){ var reader = new FileReader(file); reader.onloadend = function (e) { //webkit的BlobBuilder已经不支持了; fileWriter.write(new Blob([this.result + text], { type: "text/plain" })); $df.resolve(text); }; reader.readAsText(file); }); */ }, errorHandler); return $df; }; /** * @desc 直接通过fileEntry获取文件text; * @param fileEntry 文件的句柄; * @return 延迟对象,参数为text文本; * */ p.getText = function (fileEntry) { var $df = $.Deferred(); fileEntry.file(function (file) { var reader = new FileReader(); reader.onloadend = function (e) { $df.resolve( this.result ); }; reader.readAsText(file); }); return $df; }; /** * @desc 复制文件或者复制文件夹; * @param file文件或者文件夹来源 * @param to文件或者文件夹要复制到的目录 * @param 新的文件名字 * @return 延迟对象,参数为新文件的entry文本; * */ p.copy = function(file, to, name) { var $df = $.Deferred(); //如果不是文件或者文件夹类型就报错; isDic(file); isDic(to); file.copyTo(to, name ,function( newEntry ) { $df.resolve(newEntry); }, errorHandler); return $df; }; /** * @desc 移动文件或者目录; * @param 文件路径或者文件夹路径 * @param 文件夹或者文件要复制到的地方 * @param Optional 新文件的名字 * */ p.move = function(url, to, newName) { var $df = $.Deferred(); var dir = url.split("/"); var fileName; if(url.lastIndexOf(".") !== -1) { fileName = dir.pop(); }; dir = dir.join("/").replace(/^\/*|\/*$/gi,""); p.createDir(dir).then(function(entry, p) { if(fileName) { p.createFile(fileName, entry).then(function(fileEntry) { p.createDir(to).done(function(destEntry) { newName ? fileEntry.moveTo(destEntry, newName):fileEntry.moveTo(destEntry); }) }); }else{ p.createDir(to).done(function(dirEntry) { newName?entry.moveTo(dirEntry, newName):entry.moveTo(dirEntry); }); } }); return $df; }; /** * @param 直接调用move接口; * @param fileUrl原来文件的名字; * @param newName 新文件的名字; * */ p.rename = function(fileUrl, newName) { var $df = $.Deferred(); var dir = fileUrl.split("/"); var fileName; if(fileUrl.lastIndexOf(".") !== -1) { fileName = dir.pop(); }; dir = dir.join("/").replace(/^\/*|\/*$/gi,""); if(fileName) { p.move(fileUrl,dir,newName); }else{ //是文件夹要单独处理 fs.createDir(fileUrl).done(function(dirEntry, p) { dirEntry.getParent(function(parentEntry) { p.move(fileUrl, parentEntry.fullPath,newName); }); }); }; }; /** * @desc 删除文件 * @param 要删除的文件夹或者文件; * @return 成功就返回success; * */ p.remove = function(fileUrl) { var $df = $.Deferred(); var dir = fileUrl.split("/"); var fileName; if(fileUrl.lastIndexOf(".") !== -1) { fileName = dir.pop(); dir = dir.join("/").replace(/^\/*|\/*$/gi,""); p.createDir(dir).then(function(entry, p) { p.createFile(fileName, entry).then(function(fileEntry) { fileEntry.remove(function(){ $df.resolve("success"); },errorHandler); }); }); }else{ dir = dir.join("/").replace(/^\/*|\/*$/gi,""); p.createDir(dir).then(function(entry, p) { entry.removeRecursively(function(){ $df.resolve("success"); },errorHandler); }); }; return $df; }; /** * @param dirEntry * @return Deferred [] dirEntry */ p.list = function(dirEntry) { var $df = $.Deferred(); if( !dirEntry.createReader ) alert("不是目录类型"); var reader = dirEntry.createReader(); reader.readEntries(handleSuccess, errorHandler); function handleSuccess(entries) { var len = entries.length; var list = []; for(var i=0; i<len; i++) { list.push(entries[i].name); }; $df.resolve(list); }; return $df; } /** * * */ p.re = function() {}; var fs = new _FS; var FS = function() {}; //继承一下; FS.prototype = fs; /* * @desc 可以是复制文件或者目录; * @param 文件路径或者文件夹路径 * @param 文件夹或者文件要复制到的地方 * @param Optional 新文件的名字 * */ FS.prototype.copy = function(url, to, newName) { var $df = $.Deferred(); var dir = url.split("/"); var fileName; if(url.lastIndexOf(".") !== -1) { fileName = dir.pop(); }; dir = dir.join("/").replace(/^\/*|\/*$/gi,""); p.createDir(dir).then(function(entry, p) { if(fileName) { p.createFile(fileName, entry).then(function(fileEntry) { p.createDir(to).done(function(destEntry) { p.copy(fileEntry, destEntry, newName); }) }); }else{ p.createDir(to).done(function(dirEntry) { p.copy(entry, dirEntry, newName); }); } }); return $df; }; /** * @desc 直接读取text文件并发挥数据 * @param 文件地址; * @param root,文件系统的根目录; * @return 延迟对象 参数为text文本; * */ FS.prototype.readTextFile = function(url) { var $df = $.Deferred(); var dir = url.split("/"); var fileName = dir.pop(); dir = dir.join("/").replace(/^\/*|\/*$/gi,""); if(fileName.indexOf(".txt") === -1) { fileName += ".txt"; }; p.createDir( dir ).done(function (dirEntry) { p.getFile( fileName , dirEntry).then(function (fileEntry) { p.getText(fileEntry).done(function(text) { $df.resolve(text); }); }); }); return $df; }; /** * @desc 新建或者往已经存在的txt写信息; * @param "nono/hehe/xx/xx.txt" //文件的目录; * @param text 要添加的文本text; * @return $Deferred; * */ FS.prototype.writeTextFile = function(url, text) { var $df = $.Deferred(); var dir = url.split("/"); var fileName = dir.pop(); dir = dir.join("/").replace(/^\/*|\/*$/gi,""); p.createDir( dir ).done(function (dirEntry) { p.createFile(fileName,dirEntry).done(function(fileEntry) { p.writeText( text , fileEntry).then(function () { $df.resolve(text); }); }); }); return $df; }; return FS; function isDic (entry) { if( entry.filesystem && entry.fullPath && entry.name ) return true; else throw new Error("参数应该为 DicEntry 或者fileEntry类型"); }; function errorHandler(err) { var msg = 'An error occured: '; switch (err.code) { case FileError.NOT_FOUND_ERR: msg += 'File or directory not found'; break; case FileError.NOT_READABLE_ERR: msg += 'File or directory not readable'; break; case FileError.PATH_EXISTS_ERR: msg += 'File or directory already exists'; break; case FileError.TYPE_MISMATCH_ERR: msg += 'Invalid filetype'; break; default: msg += 'Unknown Error'; break; }; console.log(msg); }; })();
API以及测试代码也全部给粗来, chrome下也( •̀ ω •́ )y可直接调试:
<html> <head> <meta charset="utf-8"/> <title>file system</title> </head> <script src="http://cdn.bootcss.com/jquery/1.8.2/jquery.js"></script> <pre> //实现之前我们要先实例化该组件对象; var fs = new FS(); //因为是文件系统api是异步的,我们需要用到延迟对象,让流程清晰一点; 这个是在根目录下新建4-19这个文件夹 fs.init().then(function() { return fs.createDir("4-19"); }) init完毕以后, 直接写文件到txt,如果文件夹或者文件不存在,会自动创建; fs.init().then(function () { 往文件写入txt文本数据; fs.writeTextFile("/4-19/hehe1.txt","ddd").done(function(text){ console.log(text); }); }); init完毕以后, 直接读取文件的text并作为返回; fs.init().then(function () { 往文件写入txt文本数据; fs.readTextFile("/4-19/hehe1.txt").done(function(text){ console.log("读取文件----/4-19/hehe.txt"); console.log(text); }); }); 往目录/4-19/的文件hehe.txt 添加(append)文本; fs.init().then(function() { return fs.createDir("4-19"); }).then(function (entry) { fs.createFile("hehe.txt", entry).then(function (fileEntry, p) { fs.prePendText("hehenono", fileEntry); }); }); 往目录/4-19/的文件hehe.txt的前面添加(prePendText)文本; fs.init().then(function() { return fs.createDir("4-19"); }).then(function (entry) { fs.createFile("hehe.txt", entry).then(function (fileEntry, p) { fs.prePendTexfst("hehenono", fileEntry); }); }); //往后面添加文本 fs.init().then(function() { return fs.createDir("4-19"); }).then(function (entry) { fs.createFile("hehe.txt", entry).then(function (fileEntry, p) { fs.appendText("sssss", fileEntry); }); }); 从文件夹"/4-19/hehe.txt"复制文件到copycat_hehe的目录; fs.init().then(function() { return fs.createDir("4-19"); }).then(function (entry) { fs.copy("/4-19/hehe.txt","copycat_hehe","copy_hehe.txt"); }); 删除copycat_hehe/copy_hehe.txt这个文件 fs.init().then(function() { }).then(function () { fs.remove("copycat_hehe/copy_hehe.txt"); }); 复制当前的文件到,4-19-c, 没有复制子文件或者只目录; fs.init().then(function() { }).then(function () { fs.move("4-19 ","4-19-c"); }); 只有复制文件,没有复制文件内容 fs.init().then(function() { }).then(function () { fs.move("reName--4-19/hehe1.txt ","reHehe"); }); 删除文件或者是删除文件夹; fs.init().then(function() { }).then(function () { fs.remove("nono"); }); 重新命名,可以是文件或者文件夹 fs.init().then(function() { }).then(function () { fs.rename("4-19","reName--4-19") }); 通过fs.list方法获取根目录的目录结构; fs.init().then(function () { return fs.createDir("./"); }).then(function (entry) { return fs.list(entry) }).done(function(list) { console.log(list); }); //新建一个叫做nono的目录; fs.init().then(function () { return fs.createDir("nono/"); }).done(function (entry) { }); </pre> <body> <script> var FS = (function () { /** * FF火狐不支持fileSystem ;http://dev.w3.org/2009/dap/file-system/file-dir-sys.html * * */ var _FS = function() {}; var p = _FS.prototype; //init应该创建一个文件系统,可以是临时或者是永久的; p.init = function (storeType) { var $df = $.Deferred(); //window.TEMPORARY 是 0 , window.PERSISTENT是1; storeType = storeType === 0 ? window.TEMPORARY : window.PERSISTENT; window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; window.requestFileSystem(storeType, 5 * 1024 * 1024, function (fs) { //把这个fs句柄绑定到实例的原型上; p.fs = fs; $df.resolve(p); }, errorHandler); return $df; }; /** * @param "hehe/xxx/dir" 新建一个目录,如果目录存在就把目录打开; * @return Deferred , @param dirEntry, @this_prototpe; * */ p.createDir = function (folders) { var $df = $.Deferred(); if(folders === "/" || folders === "./") { $df.resolve(p.fs.root, p); return $df; }; /** * @param 文件夹的数组["hehe","wawa", "lala", "dudu"] * @param 要创建文件的目录 * */ var createDir = function (folders, entry) { entry.getDirectory(folders.shift(), {create: true}, function (dirEntry) { //如果folder还有目录就调用自己,继续新建目录; 否则就resolve; var testLength = folders.length; if (testLength) { createDir(folders, dirEntry); } else { $df.resolve(dirEntry, p); } ; }, errorHandler); }; createDir(folders.split("/"), p.fs.root); return $df; }; /** * @desc 新建文件; * @param fileName 要新建的文件名字; * @param entry 文件目录入口 * @return 延迟对象, 该延迟对象的实际参数为 @文件句柄, @这个实例的原型; * */ p.createFile = function (fileName, entry) { $df = $.Deferred(); try { ; //如果文件存在就直接返回存在的文件; entry.getFile(fileName, {create: false, exclusive: true}, function (fileEntry) { $df.resolve(fileEntry, p); }, function (ex) { if (ex.name === "NotFoundError") { //否则就新建文件并返回; entry.getFile(fileName, { create: true, exclusive: true }, function (fileEntry) { $df.resolve(fileEntry, p); }, errorHandler); } else { alert("文件创建错误!"); } ; }); } catch (ex) { alert("文件打开或者创建错误!"); } ; return $df; }; /** * @desc 打开文件 * @param fileName 要新建的文件名字; * @param entry 文件目录入口 * @return 延迟对象, 该延迟对象的实际参数为 @文件句柄, @这个实例的原型; * */ p.getFile = function (fileName, entry) { $df = $.Deferred(); entry.getFile(fileName, { create: false, exclusive: true }, function (fileEntry) { $df.resolve(fileEntry, p); }, errorHandler); return $df; }; /** * @desc 对文件进行重写; * @param text 要写入的文本数据; * @param fileEntry 文件的句柄; * @return 延迟对象,参数为写入的text文本; * */ p.writeText = function(text, fileEntry) { $df = $.Deferred(); fileEntry.createWriter(function (fileWriter) { fileEntry.file(function(file){ fileWriter.onwriteend = function(){ this.truncate(this.position); $df.resolve(text); }; //chrome,ff中BlobBuilder已经不支持了; fileWriter.write(new Blob([text], { type: "text/plain" })); }); }, errorHandler); return $df; }; /** * @desc 在文件最前头添加text数据; * @param text 要写入的文本数据; * @param fileEntry 文件的句柄; * @return 延迟对象,参数为写入的text文本; * */ p .prePendText = function (text, fileEntry) { $df = $.Deferred(); fileEntry.createWriter(function (fileWriter) { fileEntry.file(function(file){ var reader = new FileReader(file); reader.onloadend = function (e) { //webkit的BlobBuilder已经不支持了; fileWriter.write(new Blob([text+this.result], { type: "text/plain" })); $df.resolve(text); }; reader.readAsText(file); }); }, errorHandler); return $df; }; /** * @desc 在文件末尾添加text; * @param text 要写入的文本数据; * @param fileEntry 文件的句柄; * @return 延迟对象,参数为写入的text文本; * */ p.appendText = function(text, fileEntry) { $df = $.Deferred(); fileEntry.createWriter(function (fileWriter) { //我们可以通过fileWrite对文件进行写入, 也可以通过file方法先获取到file对象, 然后通过FileReader对文件进行写入; fileWriter.seek(fileWriter.length); fileWriter.write( new Blob([text]), {type : "text/plasin"}); fileWriter.onwriteend = function() { $df.resolve(text); } /* fileEntry.file(function(file){ var reader = new FileReader(file); reader.onloadend = function (e) { //webkit的BlobBuilder已经不支持了; fileWriter.write(new Blob([this.result + text], { type: "text/plain" })); $df.resolve(text); }; reader.readAsText(file); }); */ }, errorHandler); return $df; }; /** * @desc 直接通过fileEntry获取文件text; * @param fileEntry 文件的句柄; * @return 延迟对象,参数为text文本; * */ p.getText = function (fileEntry) { var $df = $.Deferred(); fileEntry.file(function (file) { var reader = new FileReader(); reader.onloadend = function (e) { $df.resolve( this.result ); }; reader.readAsText(file); }); return $df; }; /** * @desc 复制文件或者复制文件夹; * @param file文件或者文件夹来源 * @param to文件或者文件夹要复制到的目录 * @param 新的文件名字 * @return 延迟对象,参数为新文件的entry文本; * */ p.copy = function(file, to, name) { var $df = $.Deferred(); //如果不是文件或者文件夹类型就报错; isDic(file); isDic(to); file.copyTo(to, name ,function( newEntry ) { $df.resolve(newEntry); }, errorHandler); return $df; }; /** * @desc 移动文件或者目录; * @param 文件路径或者文件夹路径 * @param 文件夹或者文件要复制到的地方 * @param Optional 新文件的名字 * */ p.move = function(url, to, newName) { var $df = $.Deferred(); var dir = url.split("/"); var fileName; if(url.lastIndexOf(".") !== -1) { fileName = dir.pop(); }; dir = dir.join("/").replace(/^\/*|\/*$/gi,""); p.createDir(dir).then(function(entry, p) { if(fileName) { p.createFile(fileName, entry).then(function(fileEntry) { p.createDir(to).done(function(destEntry) { newName ? fileEntry.moveTo(destEntry, newName):fileEntry.moveTo(destEntry); }) }); }else{ p.createDir(to).done(function(dirEntry) { newName?entry.moveTo(dirEntry, newName):entry.moveTo(dirEntry); }); } }); return $df; }; /** * @param 直接调用move接口; * @param fileUrl原来文件的名字; * @param newName 新文件的名字; * */ p.rename = function(fileUrl, newName) { var $df = $.Deferred(); var dir = fileUrl.split("/"); var fileName; if(fileUrl.lastIndexOf(".") !== -1) { fileName = dir.pop(); }; dir = dir.join("/").replace(/^\/*|\/*$/gi,""); if(fileName) { p.move(fileUrl,dir,newName); }else{ //是文件夹要单独处理 fs.createDir(fileUrl).done(function(dirEntry, p) { dirEntry.getParent(function(parentEntry) { p.move(fileUrl, parentEntry.fullPath,newName); }); }); }; }; /** * @desc 删除文件 * @param 要删除的文件夹或者文件; * @return 成功就返回success; * */ p.remove = function(fileUrl) { var $df = $.Deferred(); var dir = fileUrl.split("/"); var fileName; if(fileUrl.lastIndexOf(".") !== -1) { fileName = dir.pop(); dir = dir.join("/").replace(/^\/*|\/*$/gi,""); p.createDir(dir).then(function(entry, p) { p.createFile(fileName, entry).then(function(fileEntry) { fileEntry.remove(function(){ $df.resolve("success"); },errorHandler); }); }); }else{ dir = dir.join("/").replace(/^\/*|\/*$/gi,""); p.createDir(dir).then(function(entry, p) { entry.removeRecursively(function(){ $df.resolve("success"); },errorHandler); }); }; return $df; }; /** * @param dirEntry * @return Deferred [] dirEntry */ p.list = function(dirEntry) { var $df = $.Deferred(); if( !dirEntry.createReader ) alert("不是目录类型"); var reader = dirEntry.createReader(); reader.readEntries(handleSuccess, errorHandler); function handleSuccess(entries) { var len = entries.length; var list = []; for(var i=0; i<len; i++) { list.push(entries[i].name); }; $df.resolve(list); }; return $df; } /** * * */ p.re = function() {}; var fs = new _FS; var FS = function() {}; //继承一下; FS.prototype = fs; /* * @desc 可以是复制文件或者目录; * @param 文件路径或者文件夹路径 * @param 文件夹或者文件要复制到的地方 * @param Optional 新文件的名字 * */ FS.prototype.copy = function(url, to, newName) { var $df = $.Deferred(); var dir = url.split("/"); var fileName; if(url.lastIndexOf(".") !== -1) { fileName = dir.pop(); }; dir = dir.join("/").replace(/^\/*|\/*$/gi,""); p.createDir(dir).then(function(entry, p) { if(fileName) { p.createFile(fileName, entry).then(function(fileEntry) { p.createDir(to).done(function(destEntry) { p.copy(fileEntry, destEntry, newName); }) }); }else{ p.createDir(to).done(function(dirEntry) { p.copy(entry, dirEntry, newName); }); } }); return $df; }; /** * @desc 直接读取text文件并发挥数据 * @param 文件地址; * @param root,文件系统的根目录; * @return 延迟对象 参数为text文本; * */ FS.prototype.readTextFile = function(url) { var $df = $.Deferred(); var dir = url.split("/"); var fileName = dir.pop(); dir = dir.join("/").replace(/^\/*|\/*$/gi,""); if(fileName.indexOf(".txt") === -1) { fileName += ".txt"; }; p.createDir( dir ).done(function (dirEntry) { p.getFile( fileName , dirEntry).then(function (fileEntry) { p.getText(fileEntry).done(function(text) { $df.resolve(text); }); }); }); return $df; }; /** * @desc 新建或者往已经存在的txt写信息; * @param "nono/hehe/xx/xx.txt" //文件的目录; * @param text 要添加的文本text; * @return $Deferred; * */ FS.prototype.writeTextFile = function(url, text) { var $df = $.Deferred(); var dir = url.split("/"); var fileName = dir.pop(); dir = dir.join("/").replace(/^\/*|\/*$/gi,""); p.createDir( dir ).done(function (dirEntry) { p.createFile(fileName,dirEntry).done(function(fileEntry) { p.writeText( text , fileEntry).then(function () { $df.resolve(text); }); }); }); return $df; }; return FS; function isDic (entry) { if( entry.filesystem && entry.fullPath && entry.name ) return true; else throw new Error("参数应该为 DicEntry 或者fileEntry类型"); }; function errorHandler(err) { var msg = 'An error occured: '; switch (err.code) { case FileError.NOT_FOUND_ERR: msg += 'File or directory not found'; break; case FileError.NOT_READABLE_ERR: msg += 'File or directory not readable'; break; case FileError.PATH_EXISTS_ERR: msg += 'File or directory already exists'; break; case FileError.TYPE_MISMATCH_ERR: msg += 'Invalid filetype'; break; default: msg += 'Unknown Error'; break; }; console.log(msg); }; })(); </script> <script> //实现之前我们要先实例化该组件对象; var fs = new FS(); //因为是文件系统api是异步的,我们需要用到延迟对象,让流程清晰一点; /*这个是在根目录下新建4-19这个文件夹 fs.init().then(function() { return fs.createDir("4-19"); }) /* //init完毕以后, 直接写文件到txt,如果文件夹或者文件不存在,会自动创建; fs.init().then(function () { //往文件写入txt文本数据; fs.writeTextFile("/4-19/hehe1.txt","ddd").done(function(text){ console.log(text); }); }); */ /* //init完毕以后, 直接读取文件的text并作为返回; fs.init().then(function () { //往文件写入txt文本数据; fs.readTextFile("/4-19/hehe1.txt").done(function(text){ console.log("读取文件----/4-19/hehe.txt"); console.log(text); }); }); */ /* //往目录/4-19/的文件hehe.txt 添加(append)文本; fs.init().then(function() { return fs.createDir("4-19"); }).then(function (entry) { fs.createFile("hehe.txt", entry).then(function (fileEntry, p) { fs.prePendText("hehenono", fileEntry); }); }); */ //往目录/4-19/的文件hehe.txt的前面添加(prePendText)文本; /* fs.init().then(function() { return fs.createDir("4-19"); }).then(function (entry) { fs.createFile("hehe.txt", entry).then(function (fileEntry, p) { fs.prePendTexfst("hehenono", fileEntry); }); }); */ /* //往后面添加文本 fs.init().then(function() { return fs.createDir("4-19"); }).then(function (entry) { fs.createFile("hehe.txt", entry).then(function (fileEntry, p) { fs.appendText("sssss", fileEntry); }); }); */ //从文件夹"/4-19/hehe.txt"复制文件到copycat_hehe的目录; /* fs.init().then(function() { return fs.createDir("4-19"); }).then(function (entry) { fs.copy("/4-19/hehe.txt","copycat_hehe","copy_hehe.txt"); }); */ //删除copycat_hehe/copy_hehe.txt这个文件 /* fs.init().then(function() { }).then(function () { fs.remove("copycat_hehe/copy_hehe.txt"); }); */ /*复制当前的文件到,4-19-c, 没有复制子文件或者只目录; fs.init().then(function() { }).then(function () { fs.move("4-19 ","4-19-c"); }); */ /*只有复制文件,没有复制文件内容 fs.init().then(function() { }).then(function () { fs.move("reName--4-19/hehe1.txt ","reHehe"); }); */ /** * 删除文件或者是删除文件夹; fs.init().then(function() { }).then(function () { fs.remove("nono"); }); * */ /** * 重新命名,可以是文件或者文件夹 fs.init().then(function() { }).then(function () { fs.rename("4-19","reName--4-19") }); * */ /** *通过fs.list方法获取根目录的目录结构; fs.init().then(function () { return fs.createDir("./"); }).then(function (entry) { return fs.list(entry) }).done(function(list) { console.log(list); }); */ //新建一个叫做nono的目录; fs.init().then(function () { return fs.createDir("nono/"); }).done(function (entry) { }); /** * https://github.com/ebidel/filer.js/blob/master/src/filer.js * */ </script> </body> </html>
火狐官方的404太可爱了, 眼睛会动;
老外写的filesystem库, 托管在github上面哦, 可以参考学习,点击带我飞吧;
作者: NONO
出处:http://www.cnblogs.com/diligenceday/
QQ:287101329