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是在对象上面的方法, 这个主要是处理目录,比如打开目录, 或者新建目录

ParameterTypeNullableOptionalDescription
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 Flags
  • If create and exclusive are both true and the path already exists, getDirectory MUST fail.
  • If create is true, the path doesn't exist, and no other error occurs, getDirectory MUST create and return a corresponding DirectoryEntry.
  • If create is not true and the path doesn't exist, getDirectory MUST fail.
  • If create is not true and the path exists, but is a file, getDirectory MUST fail.
  • Otherwise, if no other error occurs, getDirectory MUST return a DirectoryEntry corresponding to path.
successCallback EntryCallback A callback that is called to return the DirectoryEntry selected or created.
errorCallback ErrorCallback A callback that is called when errors happen.

   

  getFile这个是获取文件, 作用是打开文件或者新建文件

ParameterTypeNullableOptionalDescription
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 Flags
  • If create and exclusive are both true, and the path already exists, getFile MUST fail.
  • If create is true, the path doesn't exist, and no other error occurs, getFile MUST create it as a zero-length file and return a corresponding FileEntry.
  • If create is not true and the path doesn't exist, getFile MUST fail.
  • If create is not true and the path exists, but is a directory, getFile MUST fail.
  • Otherwise, if no other error occurs, getFile MUST return a FileEntry corresponding to path.
successCallback EntryCallback A callback that is called to return the File selected or created.
errorCallback 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.

ParameterTypeNullableOptionalDescription
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.

ParameterTypeNullableOptionalDescription
successCallback FileCallback A callback that is called with the File.
errorCallback ErrorCallback A callback that is called when errors happen.
Return type: void
 
 
文件上提供了remove
文件夹上提供了removeremoveRecursively方法;
以及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);
        };
    })();
View Code

 

   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 

posted @ 2015-04-19 23:13  方方和圆圆  阅读(1856)  评论(1编辑  收藏  举报

再过一百年, 我会在哪里?