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 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这个是获取文件, 作用是打开文件或者新建文件

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

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

文件夹上提供了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);
        };
    })();

  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上面哦, 可以参考学习,点击带我飞吧

时间: 04-17

HTML5文件系统API和资料整理的相关文章

HTML5之本地文件系统API - File System API

HTML5之本地文件系统API - File System API 2014-06-03 17:54 19991人阅读 评论(0) 收藏 举报 目录(?)[+] 新的HTML5标准给我们带来了大量的新特性和惊喜,例如,画图的画布Canvas,多媒体的audio和video等等.除了上面我们提到的,还有比较新的特性 - File System API,它能够帮助我们来突破沙箱访问我们本地的文件系统,从而有效的弥补桌面和web应用之间的鸿沟.在今天这篇文章中,我们将会介绍基本的File system

iOS开发资料整理

Please help me contribute to this list, for non-experience iOS developers or someone who need a come-in-handy library list to refer or to use in their projects. Fork, edit and send a PR are all things you can do! Table of Contents UI Component// UI组件

HTML5之API

HTML5就是牛,可以直接播放音视频,还可以作图: 一.HTML5中播放视频和音频: 加载时直接播放音频的方式:new Audio("BY2.mp3").play(); <div> <h1>播放器</h1> <!-- controls:显示播放控件; --> <h3>视频</h3> <video id="mpv" width="60%" height="30%

HTML5 Geolocation API精确性[转载]

大家都知道,HTML5 Geolocation 可以使用 IP 地址.基于 Web 的数据库.无线网络连接和三角测量或 GPS 技术来确定经度和纬度. 问题: 在一个基于地理位置服务的个人业余项目(小伙伴在哪儿)中,发现用PC获取的地理位置与手机端获取的地理信息存在微小的差距,PC端会经常出现获取不到地理位置的情况,PC端和手机端的Geolocation是否有什么底层实现方面的差别呢,HTML5又是根据什么原则来确定应该采用何种方式来确定经度和纬度信息呢? 带着这个问题,作者查阅了一些资料,得出

HTML5 History API

以Html5 History API为关键词搜索,会得到很多结果,我仅根据自己的使用整理. 1.两个API pushState和replaceState. pushState向浏览器历史记录里增加一个状态,供浏览器后退前进时使用,用法 history.pushState(data, '页面标题', url); replaceState就是替换某个状态,参数和pushState一样. 2.一个事件 onpopstate. 用户点击了前进或者后退就会触发,而不是使用pushState或者replac

文件系统API的基本概念

文件系统API(File System API)模拟网络应用程序可以导航到的本地文件系统.你可以开发应用在一个沙盒的虚拟文件系统中读.写.创建以及索引文件. 该文件系统API与其他相关的API交互.它基于文件写入API(File Writer API),而后者又基于文件API(File API).每一个API都具有不同的功能.这些API对于网络应用而言是一个巨大的进化飞跃,使得它们能够缓存和处理大量级的数据. 关于这篇文档EDIT 这篇介绍讨论了文件系统API中的基本概念和术语.它将给出一个大致

不错的Nodejs或者JS资料整理

资料整理 Node.js官网 - 可以下载到Node.js以及查看官方文档 Node.js教程 - 菜鸟教程网 Javascript模块化编程(一):模块的写法 - 阮一峰老师的日志,很值得看 CommonJS官网 requireJS官网 - AMD规范在其中 seaJS官网 - CMD规范在其中 request模块 cheerio模块

Html5 Selectors API

新QuerySelector方法 querySelector():根据指定的选择规则,返回在页面中找到的第一匹配元素 querySelectorAll():根据指定规则返回页面中所有相匹配的元素 实例: 1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <meta http-equiv="Content-Type" content="text/html; char

iOS 开发学习资料整理(持续更新)

"如果说我看得比别人远些,那是因为我站在巨人们的肩膀上." ---牛顿 iOS及Mac开源项目和学习资料[超级全面] http://www.kancloud.cn/digest/ios-mac-study/84557 iOS 学习资料整理 https://segmentfault.com/a/1190000002473595#articleHeader16 iOS.mac开源项目及库 https://github.com/Tim9Liu9/TimLiu-iOS Swift语言 http