返回 导航

Cordova

hangge.com

Cordova - file插件的使用详解(文件的创建、读写,文件夹创建等)

作者:hangge | 2016-05-21 10:10
Cordova 提供了一个 file 插件,通过这个插件我们很方便地实现在各种设备下对文件、和文件夹进行访问,编辑等各种操作。

一、添加File插件
首先我们要在“终端”中进入工程所在的目录,然后运行如下命令添加 file 插件:
cordova plugin add cordova-plugin-file

二、普通文件的读取与写入

1,文件写入(持久化保存)
在iOS中,下面代码会将文件写入到 Documents 目录(应用程序用户文档目录)下:
<!DOCTYPE html>
<html>
    <head>
        <title>Capture Photo</title>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
        <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
        <script type="text/javascript" charset="utf-8">
            //创建并写入文件
            function createAndWriteFile(){
              //持久化数据保存
              window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {

                console.log('打开的文件系统: ' + fs.name);
                fs.root.getFile("hangge.txt", { create: true, exclusive: false },
                 function (fileEntry) {

                    console.log("是否是个文件?" + fileEntry.isFile.toString());
                    // fileEntry.name == 'hangge.txt'
                    // fileEntry.fullPath == '/hangge.txt'
                    //文件内容
                    var dataObj = new Blob(['欢迎访问hangge.com'], { type: 'text/plain' });
                    //写入文件
                    writeFile(fileEntry, null);

                }, onErrorCreateFile);

              }, onErrorLoadFs);
            }

            //将内容数据写入到文件中
            function writeFile(fileEntry, dataObj) {
                //创建一个写入对象
                fileEntry.createWriter(function (fileWriter) {

                    //文件写入成功
                    fileWriter.onwriteend = function() {
                        console.log("Successful file read...");
                    };

                    //文件写入失败
                    fileWriter.onerror = function (e) {
                        console.log("Failed file read: " + e.toString());
                    };
                    
                    //写入文件
                    fileWriter.write(dataObj);
                });
            }

            //文件创建失败回调
            function  onErrorCreateFile(error){
              console.log("文件创建失败!")
            }

            //FileSystem加载失败回调
            function  onErrorLoadFs(error){
              console.log("文件系统加载失败!")
            }
        </script>
    </head>
    <body style="padding-top:50px">
        <button style="font-size:23px;" onclick="createAndWriteFile();">创建并写入文件</button>
    </body>
</html>
可以看到 hangge.txt 文件创建成功,打开后里面内容也写入成功。


2,持久化文件保存路径设置:iOS平台
config.xml 文件中,我们可以配置修改持久话化文件保存位置(Persistent storage location)。
如何不配置的话,从前面样例可以看到。默认是保存在程序的 Documents 文件目录下,也就是如下配置:
<preference name="iosPersistentFileLocation" value="Compatibility" />
但保存在这里有个副作用,就是使用 iTunes 可以看到这些文件。如果要持久化保存很多文件,又不希望和普通用户文件混起来。我们可以修改成如下配置:
<preference name="iosPersistentFileLocation" value="Library" />
可以看到文件保存到应用的 Library 文件夹下了:


3,持久化文件保存路径设置:Android平台
同样的,我们也可以在 config.xml 文件中配置修改 Android 设备中持久化文件保存位置(Persistent storage location)。
如果不配置,或者进行如下配置的话。持久化文件是保存在 /data/data/<packageId> 下面。 
<preference name="AndroidPersistentFileLocation" value="Internal" />
修改成如下配置的话,如果设备有SD卡(或等效的存储分区)。那么持久性文件将被存储在该空间的根路径下。
<preference name="AndroidPersistentFileLocation" value="Compatibility" />

4,创建临时文件(将文件写入到临时文件夹下)
在iOS系统中,下面代码会将文件写入到 tmp 目录下。当系统空间不足或是资源不足的时候,临时文件会被系统删除。
同上面的样例相比,这里只改了一个地方(高亮处)。
//创建并写入文件
function createAndWriteFile(){
  //临时数据保存
  window.requestFileSystem(LocalFileSystem.TEMPORARY, 5 * 1024 * 1024, function (fs) {

    console.log('打开的文件系统: ' + fs.name);
    fs.root.getFile("hangge.txt", { create: true, exclusive: false },
     function (fileEntry) {

        console.log("是否是个文件?" + fileEntry.isFile.toString());
        // fileEntry.name == 'hangge.txt'
        // fileEntry.fullPath == '/hangge.txt'
        //文件内容
        var dataObj = new Blob(['欢迎访问hangge.com'], { type: 'text/plain' });
        //写入文件
        writeFile(fileEntry, dataObj);

    }, onErrorCreateFile);

  }, onErrorLoadFs);
}

5,文件末尾写入新内容
下面改造下 writeFile() 方法,增加一个 isAppend 参数。用来表示数据写入是完全覆盖,还是追加(append)到末尾。
//将内容数据写入到文件中(支持追加内容)
function writeFile(fileEntry, dataObj, isAppend) {
    //创建一个写入对象
    fileEntry.createWriter(function (fileWriter) {

        //文件写入成功
        fileWriter.onwriteend = function() {
            console.log("Successful file read...");
        };

        //文件写入失败
        fileWriter.onerror = function (e) {
            console.log("Failed file read: " + e.toString());
        };

        //如果是最加内容,则定位到文件尾部
        if (isAppend) {
            try {
                fileWriter.seek(fileWriter.length);
            }
            catch (e) {
                console.log("file doesn't exist!");
            }
        }
        fileWriter.write(dataObj);
    });
}
使用方式如下:
var dataObj = new Blob(['\n值得您每天来看看!'], { type: 'text/plain' });
writeFile(fileEntry, dataObj, true);

6,读取文件
下面将之前创建的 hangge.txt 文件中的内容读取出来,并显示。

下面 readFile() 方法接收传入的 FileEntry 对象,并读取对象内容。
//读取文件
function readFile(fileEntry) {
    fileEntry.file(function (file) {
        var reader = new FileReader();
        reader.onloadend = function() {
            alert(this.result);
        };
        reader.readAsText(file);
    }, onErrorReadFile);
}

//读取文件失败响应
function onErrorReadFile(){
  console.log("文件读取失败!");
}

三、文件夹操作
下面代码在 Documents 目录(应用程序用户文档目录)下创建子文件夹:assets/images
//创建并写入文件
function createAndWriteFile(){
  //临时数据保存
  window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {

    console.log('打开的文件系统: ' + fs.name);
    fs.root.getDirectory('assets', { create: true }, function (dirEntry) {
        dirEntry.getDirectory('images', { create: true }, function (subDirEntry) {
            //createFile(subDirEntry, "hangge.txt");
        }, onErrorGetDir);
    }, onErrorGetDir);

  }, onErrorLoadFs);
}

//文件夹创建失败回调
function onErrorGetDir(error){
  console.log("文件夹创建失败!")
}

//FileSystem加载失败回调
function  onErrorLoadFs(error){
  console.log("文件系统加载失败!")
}

四、二进制文件(binary file)操作
1,保存二进制文件
下面代码从网络上获取一张图片,并保存到本地。
<!DOCTYPE html>
<html>
    <head>
        <title>Capture Photo</title>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
        <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
        <script type="text/javascript" charset="utf-8">
            //下载图片
            function downloadImage(){
              
              window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {

                console.log('打开的文件系统: ' + fs.name);
                getSampleFile(fs.root);

              }, onErrorLoadFs);
            }

            //获取图片
            function getSampleFile(dirEntry) {
                var xhr = new XMLHttpRequest();
                xhr.open('GET', 'http://www.hangge.com/blog/images/logo.png', true);
                xhr.responseType = 'blob';

                xhr.onload = function() {
                    if (this.status == 200) {
                        var blob = new Blob([this.response], { type: 'image/png' });
                        saveFile(dirEntry, blob, "hangge.png");
                    }
                };
                xhr.send();
            }

            //保存图片文件
            function saveFile(dirEntry, fileData, fileName) {
                dirEntry.getFile(fileName, { create: true, exclusive: false }, function (fileEntry) {
                    writeFile(fileEntry, fileData);
                }, onErrorCreateFile);
            }

            //将图片数据写入到文件中
            function writeFile(fileEntry, dataObj, isAppend) {
              //创建一个写入对象
              fileEntry.createWriter(function (fileWriter) {

                  //文件写入成功
                  fileWriter.onwriteend = function() {
                      console.log("Successful file write...");
                      if (dataObj.type == "image/png") {
                          readBinaryFile(fileEntry);
                      }
                      else {
                          readFile(fileEntry);
                      }
                  };

                  //文件写入失败
                  fileWriter.onerror = function(e) {
                      console.log("Failed file write: " + e.toString());
                  };

                  //写入文件
                  fileWriter.write(dataObj);
              });
          }

          //文件创建失败回调
          function  onErrorCreateFile(error){
            console.log("文件创建失败!")
          }

          //FileSystem加载失败回调
          function  onErrorLoadFs(error){
            console.log("文件系统加载失败!")
          }
        </script>
    </head>
    <body style="padding-top:50px">
        <button style="font-size:23px;" onclick="downloadImage();">下载图片</button>
    </body>
</html>

2,读取二进制文件
下面代码读取前面下载下来的图片(hangge.png),并在 image 元素中显示。
<!DOCTYPE html>
<html>
    <head>
        <title>Capture Photo</title>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
        <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
        <script type="text/javascript" charset="utf-8">
            //加载图片
            function loadImage(){
              
              window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {

                console.log('打开的文件系统: ' + fs.name);
                fs.root.getFile("hangge.png", { create: true, exclusive: false },
                 function (fileEntry) {
                    readBinaryFile(fileEntry);
                }, onErrorCreateFile);

              }, onErrorLoadFs);
            }

            //读取图片文件
            function readBinaryFile(fileEntry) {
                fileEntry.file(function (file) {
                    var reader = new FileReader();

                    reader.onloadend = function() {
                        //加载成功显示图片
                        var blob = new Blob([new Uint8Array(this.result)], { type: "image/png" });
                        displayImage(blob);
                    };

                    reader.readAsArrayBuffer(file);

                }, onErrorReadFile);
            }

            //显示图片
            function displayImage(blob) {
                var elem = document.getElementById('imageFile');
                elem.src = window.URL.createObjectURL(blob);
            }

            //文件创建失败回调
            function  onErrorCreateFile(error){
              console.log("文件创建失败!")
            }

            //读取文件失败响应
            function onErrorReadFile(){
              console.log("文件读取失败!");
            }

            //FileSystem加载失败回调
            function  onErrorLoadFs(error){
              console.log("文件系统加载失败!")
            }
        </script>
    </head>
    <body style="padding-top:50px">
        <button style="font-size:23px;" onclick="loadImage();">加载图片</button>
        <image id="imageFile"/>
    </body>
</html>

3,更便捷的显示图片办法
要将设备中的图片显示在页面上,前面的样例做法是先的到这个图片的 FileEntry 对象,然后读出出 Blob 数据,做最后将 Blob 数据通过 window.URL.createObjectURL() 方法创建个url传递给页面的 img 元素 src
其实还有更简单的办法,得到图片的 FileEntry 对象后,通过其 toURL() 方法即可将其 url 赋给 img 元素 src 属性即可。
下面同样以加载显示 Documents 目录下的 hangge.png 图片为例:
<!DOCTYPE html>
<html>
    <head>
        <title>Capture Photo</title>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
        <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
        <script type="text/javascript" charset="utf-8">
            //加载图片
            function loadImage(){
              
              window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {

                console.log('打开的文件系统: ' + fs.name);
                fs.root.getFile("hangge.png", { create: true, exclusive: false },
                 function (fileEntry) {
                    displayImageByFileURL(fileEntry);
                }, onErrorCreateFile);

              }, onErrorLoadFs);
            }

            //显示图片
            function displayImageByFileURL(fileEntry) {
                var elem = document.getElementById('imageFile');
                elem.src = fileEntry.toURL();
            }

            //文件创建失败回调
            function  onErrorCreateFile(error){
              console.log("文件创建失败!")
            }

            //FileSystem加载失败回调
            function  onErrorLoadFs(error){
              console.log("文件系统加载失败!")
            }
        </script>
    </head>
    <body style="padding-top:50px">
        <button style="font-size:23px;" onclick="loadImage();">加载图片</button>
        <img id="imageFile"/>
    </body>
</html>

五、使用cdvfile protocol 更快捷地定位到文件、文件夹
通过 cdvfile 协议,我们可以很方便的访问设备文件、文件夹。
cdvfile://localhost/persistent|temporary|another-fs-root*/path/to/file
1,在 html 页面中直接通过 cdvfile:// 路径来加载文件。
还是同上面样例一样,在页面上显示同一张图片:
<img src="cdvfile://localhost/persistent/hangge.png" />

2,复制文件
下面将 Documents 目录下的 hangge.png 复制到 tmp 目录下,并改名为 temp.png
这里通过 FileTransfer 对象的 copyTo() 方法进行复制,如果想要实现移动的话则改成 moveTo() 方法即可。
function copyFile(){
  window.resolveLocalFileSystemURL('cdvfile://localhost/persistent/hangge.png',
    function(fileEntry) {

      window.resolveLocalFileSystemURL('cdvfile://localhost/temporary',
        function(dirEntry) {
            fileEntry.copyTo(dirEntry, "temp.png", successCallback, errorCallback);
        },
			  function(error){console.log("创建失败!")});

    },
    function(error){console.log("创建失败!")});
}

//文件复制成功
function  successCallback() {
 console.log("文件复制成功!")
}

//文件复制失败
function  errorCallback() {
 console.log("文件复制失败!")
}
评论

全部评论(3)

回到顶部