文章出處

  來著火狐開發網絡的官方文檔:點我打開 ;

  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 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()