js文件操作

JavaScript文件操作

HTML5新增FileReader API和FileSystem API。其中FileReader API负责读取文件内容,FileSystem API负责本地文件系统的有限操作。另外,HTML5增强了HTML4的文件域功能,允许提交多个文件。

学习重点

  • 使用FileList对象。
  • 使用Blob对象。
  • 使用FileReader对象。
  • 使用ArrayBuffer对象和ArrayBufferView对象。
  • 使用FileSystem API。

访问文件域

HTML5在HTML4文件域的基础上为File控件新添multiple属性,允许用户在一个File控件内选择和提交多个文件。

  • 实例1】下面实例设计在文档中插入一个文件域,允许用户同时提交多个文件。
<input type="file" multiple>

为了方便用户在脚本中访问这些将要提交的文件,HTML5新增了FileList和File对象。

  • FileList:表示用户选择的文件列表。
  • File:表示File控件内的每一个被选择的文件对象。FileList对象为这些File对象的列表,代表用户选择的所有文件。
  • 实例2】下面实例演示了如何使用FileList和File对象访问用户提交的文件名称列表。
<script>
    window.onload = function() {
     
     
        var btn = document.getElementById("btn");
        btn.onclick = function() {
     
     
            // document.getElementById("file").files ==> 返回FileList对象
            for (var i = 0; i < document.getELementById("file").files.length; i++) {
     
     
                var file = document.getElementById("file").files[i];
                console.log(file.name);
            }
        };
    }
</script>

<body>
    <input type="file" id="file" multiple>
    <input type="button" id="btn" value="文件上传">
</body>

提示:File对象包含两个属性:name属性表示文件名,但不包括路径;lastModifiedDate属性表示文件的最后修改日期。

使用Blob对象

HTML5的Blob对象用于存储二进制数据,还可以设置存储数据的MIME类型,其他HTML5二进制对象继承Blob对象。

访问Blob

Blob对象包含两个属性:

  • size:表示一个Blob对象的字节长度。

  • type:表示Blob的MIME类型,如果为未知类型,则返回一个空字符串。

  • 实例1】下面实例演示了如何获取文件域的第一个Blob对象,并访问该文件的长度和文件类型。

<script>
    function ShowFileType() {
    
    
        var file = document.getElementById("file").files[0];
        console.log(file.size);
        console.log(file.type);
    }
</script>

<body>
    <input type="file" id="file" multiple>
    <input type="button" id="btn" onclick="ShowFileType()" value="文件上传">
</body>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KSAP4fLb-1603411823622)(/Users/mac/Desktop/MarkDown /Javascript/js复习笔记/js复习笔记十三 /1.gif)]

  • 注意:对于图像类型的文件,Blob对象的type属性都是以"image/"开头,后面是图像类型。
  • 实例2】下面实例利用Blob的type属性,判断用户选择的文件是否为图像文件。如果在批量上传时只允许上传图像文件,可以检测每个文件的type属性值,当提非图像文件时,弹出错误提示信息。并停止后面的文件上传,或者跳过该文件不上传。
<script>
    function fileUpload() {
     
     
        var file;
        for (var i = 0; i < document.getElementById("file").files.length; i++) {
     
     
            file = document.getElementById("file").files[i];
            if (!/image\/\w+/.test(file.type)) {
     
     
                alert(file.name + "不是图像文件!");
                continue;
            } else {
     
     
                // 此处加入文件上传的代码
                alert(file.name + "文件以上传");
            }
        }
    }
</script>

<body>
    <input type="file" id="file" multiple>
    <input type="button" id="btn" onclick="fileUpload()" value="文件上传">
</body>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-koG7m3HS-1603411823626)(/Users/mac/Desktop/MarkDown /Javascript/js复习笔记/js复习笔记十三 /2.gif)]

创建Blob

创建Blob对象的基本用法如下:

var blob = new Blob(blobParts, type);

参数说明如下:

  • blobParts:可选参数,数组类型,其中可以存放任意个一下以下类型的对象,这些对象中所携带的数据将被依序追加到Blob对象中。

    • ArrayBuffer对象。
    • ArrayBufferView对象。
    • Blob对象。
    • String对象。
  • type:可选参数,字符串型,设置被创建的Blob对象的type属性值,即定义Blob对象的MIME类型。默认参数值为空字符串,表示未知类型。

  • 提示:当创建Blob对象时,可以使用两个可选参数。如果不使用任何参数,创建的Blob对象的size属性值为0,即Blob对象的字节长度为0。代码如下:

    var blob = new Blob();
    
  • 实例1】下面代码演示了如何设置第一个参数。

var blob = new Blob(["4234" + "5678"]);
var shorts = new Unit16Array(buffer, 622, 128);
var blobA = new Blob([blob, shorts]);
var bytes = new Unit8Array(buffer, shorts.bytesOffset + shorts.byteLength);
var blobB = new Blob([blob, blobA, bytes]);
var blobC = new Blob([buffer, blob, blobA, bytes]);
  • 注意:ArrayBuffer和ArrayBufferView后面介绍。

  • 实例2】下面设置第二个参数。

var blob = new Blob(["4234" + "5678"],{
    
    type:"text/plain"});
  • 提示:目前主流浏览器都支持blob,但为了安全起见最好还是检查一下:
if(!window.Blob)
	alert("您的浏览器不支持Blob对象");
else
	var blob = new Blob(["1234" + "5678"], {
    
    type: "text/plain"});
  • 实例3】下面实例完整的显示了如何创建一个Blob对象。

在页面中设计一个文本区域和一个按钮,当在文本框中输入文件,然后单击”创建Blob对象“按钮后,js脚本根据用户输入文字创建二进制对象,再根据二进制对象中的内容创建URL地址,最后再页面底部动态添加一个”Blob对象文件下载“链接,单击该链接可以下载新创建的文件,使用文本文件打开,其内容为用户在文本框中输入的文字。

<script>
    function test() {
     
     
        var text = document.getElementById("textarea").value;
        var result = document.getElementById("result");
        // 创建Blob对象
        if (!window.Blob)
            result.innerHTML = "浏览器不支持Blob对象。";
        else
            var blob = new Blob([text]); // Blob中数据为文字时默认使用utf-8格式
        // 通过createObjectURL方法创建文字链接
        if (window.URL) {
     
     
            result.innerHTML = '<a download href="' + window.URL.createObjectURL(blob) + '"target="_blank">Blob对象文件下载</a>';
        }
    }
</script>

<body>
    <textarea id="textarea"></textarea><br>
    <button onclick="test()">创建Blob对象</button>
    <p id="result"></p>
</body>

在动态生成a标签中包含download属性,它设置超链接为文件下载类型。

  • 补充:HTML5支持URL对象,通过该对象的createObjectURL方法可以根据一个Blob对象的二进制数据创建一个URL地址,并返回该地址,当用户访问该URL地址时,可以直接下载原始二进制数据。

截取Blob

Blob对象包含slice()方法,它可以从Blob对象中截取一部分数据,然后将这些数据创建为一个新的Blob对象并返回。

var newBlob = blob.slice(start, end, contentType);

参数说明如下:

  • start:可选参数,整数值,设置起始位置。
    • 如果值为0,表示从第一个字节开始赋值数据。
    • 如果值为负值,且Blob对象的size属性值+start参数值大于等于0,则起始位置为Blob对象的size属性值+start参数值。
    • 如果值为负值,且Blob对象的size属性值+start参数值小于0,则起始位置为Blob对象的起点位置。
    • 如果值为正数,且大于等于Blob对象的size属性值,则起始位置为Blob对象的size属性值。
    • 如果值为正数,且小于Blob对象的size属性值,则起始位置为start参数值。
  • end:可选参数,整数值,设置终点位置。
    • 如果忽略该参数,则终点位置为Blob对象的结束位置。
    • 如果值为负数,且Blob对象的size属性值+end参数值大于等于0,则终点位置为Blob对象的size属性值+end参数值。
    • 如果值为负数,且Blob对象的size属性值+end参数值小于0,则终点位置为Blob对象的起点位置。
    • 如果值为正数,且大于等于Blob对象的size属性值,则终点位置为Blob对象的size熟悉感值。
    • 如果值为正数,且小于Blob对象的size属性值,则终点位置为end参数值。
  • contentType:可选参数,字符串值,指定新建Blob对象的MIME类型。

如果slice()方法的三个参数都省略,就相当于把一个Blob对象原样复制到一个新建的Blob对象中。当起始位置大于等于终点位置时,slice()方法复制从起始位置开始到终点位置结束这一范围中的数据。新建的Blob对象的size属性值为复制范围的长度,单位为byte。

  • 实例】下面实例演示了Blob对象的slice()方法的应用。
<script>
    function test() {
     
     
        var file = document.getElementById("file").files[0];
        if (file) {
     
     
            var file1 = file.slice(); // 复制File对象
            var file2 = file.slice(0, file.size); //复制File对象
            var file3 = file.slice(-(Math.round(file.size / 2))); //复制File对象的后半部分
            var file4 = file.slice(0, Math.roud(file.size / 2)); //复制File对象的前半部分
          	// 复制File对象,从开始处复制到结束处之前的150个字节处,并设置MIME类型
            var file5 = file.slice(0, -150, "application/plain");
        }
    }
</script>

<body>
    <input type="file" id="file" multiple>
    <input type="button" onclick="ShowFileType();" value="文件上传">
</body>

保存Blob

HTML5支持indexedDB数据库中保存Blob对象。

使用FileReader对象

FileReader能够把文件读入内存,并且读取文件中的数据。

读取文件

使用FileReader对象之前,需要实例化FileReader类型。

if(typeof FileReader == "undefined") {
    
    
	alert("当前浏览器不支持FileReader对象");
} else {
    
    
	var reader = new FileReader();
}

FileReader对象包含5个方法,其中4个用于读取文件,另一个用来中断读取操作。

  • readAsText(Blob,type):将Blob对象或文件中的数据读取为文本数据。该方法包含两个参数,其中第二个参数时文本的编码方式,默认值为UTF-8。
  • readAsBinaryString(Blob):将Blob对象或文件中的数据读取为二进制字符串。通常调用该方法将文件提交到服务器端,服务器端可以通过这段字符串存储文件。
  • readAsURL(Blob) :将Blob对象或文件中的数据读取为DataURL字符串。该方法就是将数据以一种特殊格式的URL地址形式直接读入页面。
  • readAsArrayBuffer(Blob):将Blob对象或文件中的数据读取为一ArrayBuffer对象。
  • abort():不包含参数,中断读取操作。
  • 注意:上述前4个方法都包含一个Blob对象或File对象参数,无论读取成功或失败,都不会返回读取结果,读取结果存储在result属性中。
  • 实例】下面实例演示如何在网页中读取并显示图像文件文本文件二进制代码文件
<script>
    window.onload = function() {
     
     
        var result = document.getElementById("result");
        var file = document.getElementById("file");
        if (typeof FileReader == 'undefined') {
     
     
            result.innerHTML = "<h1><当前浏览器不支持FileReader对象/h1>";
            file.setArrtibute('disabled', 'disabled');
        }
    }

    function readAsDataURL() {
     
      //将文件以Data URL格式进行读入页面
        var file = document.getElementById("file").files[0];
        if (!/image\/\w+/.test(file.type)) {
     
     
            alert("提交文件不是图像类型");
            return false;
        }
        var reader = new FileReader();
        reader.onload = function(e) {
     
     
            result.onload = function(e) {
     
     
                result.innerHTML = '<img src="' + this.result + '" alt=""/>';
            }
        }
    }

    function readAsBinaryString() {
     
      //将文件以二进制格式进行读入页面
        var file = document.getElementById("file").flies[0];
        var reader = new FileReader();
        reader.readAsBinaryString(file);
        reader.onload = function(f) {
     
     
            result.innerHTML = this.result;
        }
    }

    function readAsText() {
     
      //将文件以文本形式读入页面
        var file = document.getElementById("file").files[0];
        var reader = new FileReader();
        reader.readAsText(file);
        reader.onload = function(f) {
     
     
            result.innerHTML = this.result;
        }
    }
</script>

<body>
    <input type="file" id="file">
    <input type="button" onclick="readAsDataURL();" value="读取图像">
    <input type="button" onclick="readAsBinaryString();" value="读取二进制数据">
    <input type="button" onclick="readAsText();" value="读取文本文件">
    <div id="result" name="result"></div>
</body>

上面实例演示了如何读取显文件,用户也可以选择不显示,直接提交给服务器,然后保存到文件或数据库中。注意,fileReader对象读取的数据都保存在result属性中。

事件监测

FileReader对象提供了6个事件,用于监测文件读取状态,简单说明如下。

  • onabort:数据读取中断时触发。

  • onprogress:数据读取中触发。

  • onerror:数据读取出错时触发。

  • onload:数据读取成功完成是触发。

  • onloadstart:数据开始读取时触发。

  • onloadend:数据读取完成时触发,无论成功与失败。

  • 实例】下面实例设计当使用fileReader对象读取文件时,会发生一系列事件,控制台跟踪了读取状态先后顺序。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test</title>

</head>

<style type="text/css">

</style>

<script>
    window.onload = function() {
     
     
        var result = document.getElementById("result");
        var file = document.getElementById("file");
        if (typeof FileReader == 'undefined') {
     
     
            result.innerHTML = "<h1>当前浏览器不支持FileReader对象</h1>"
            file.setAttribute('disabled', 'disabled');
        }
    }

    function readFile() {
     
     
        var file = document.getElementById("file").files[0];
        var reader = new FileReader();
        reader.onload = function(e) {
     
     
            result.innerHTML = '<img src="' + this.result + '"alt=""/>';
            console.log("load");
        }
        reader.onprogress = function(e) {
     
     
            console.log("progress");
        }
        reader.onabort = function(e) {
     
     
            console.log("abort");
        }
        reader.onerror = function(e) {
     
     
            console.log("error");
        }
        reader.onloadstart = function(e) {
     
     
            console.log("loadstart");
        }
        reader.onloadend = function(e) {
     
     
            console.log("loadend");
        }
        reader.readAsDataURL(file);
    }
</script>

<body>
    <input type="file" id="file">
    <input type="button" value="显示图像" onclick="readFile()">
    <div name="result" id="result"></div>

</body>


</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DZCXb7nE-1603411823630)(/Users/mac/Desktop/MarkDown /Javascript/js复习笔记/js复习笔记十三 /4.gif)]

在上面实例中,当单击”显示图像“按钮后,将在页面中读入一个图像文件,同时在控制台可以看到按顺序触发的事件。用户还可以在onprogress事件中使用HTML5新增元素progress显示文件的去读进度。

使用缓存对象

HTML5新增了ArrayBuffer对象和ArrayBufferView对象。ArrayBuffer对象表示一个固定长度的缓存区,用来存储文件或网络大数据;ArrayBufferView对象表示将缓存区中的数据转换为各种类型的数值数组。

  • 注意

HTML5不允许直接对ArrayBuffer对象内的数据进行操作,需要使用ArrayBufferView对象来读写ArrayBuffer对象中的内容。

使用ArrayBuffer

ArrayBuffer对象表示一个固定长度存储二进制数据的缓存区。用户不能直接存取ArrayBuffer缓存区中的内容,必须通过ArrayBufferView对象来读写ArrayBuffer缓存区中的内容。ArrayBuffer对象包含length属性,该属性表示缓存区的长度。

  • 创建ArrayBuffer对象的方法如下:
var buffer = new ArrayBuffer(32);

参数为一个无符号长整数,用于设置缓存区的长度,单位为byte。ArrayBuffer缓存区创建成功之后,该缓存区内存储数据初始化为0。

使用ArrayBufferView

HTML5使用ArrayBufferView对象以一种标准格式来表示ArrayBuffer缓冲区中的数据。HTML5不允许直接使用ArrayBufferView对象,而是使用ArrayBufferView的子类实例来存取ArrayBuffer缓存区中的数据。

类型 字节长度 说明
Int8Array 1 8位整数数组
Unit8Array 1 8位无符号整数数组
Unit8ClampedArray 1 特殊8位无符号整数数组
Int16Array 2 16位整数数组
Unit16Array 2 16位无符号整数数组
Int32Array 4 32位整数数组
Unit32Array 4 32位无符号整数数组
Float32Array 4 32位IEEE浮点数数组
Float64Array 8 64位IEEE浮点数数组
  • 提示

Unit8ClampedArray子类用于定义一种特殊的8位无符号整数数组。该数组的作用:代替CanvasPixelArray数组用于Canvas API中。

该数组与普通8位无符号整数数组的区别:将ArrayBuffer存储区中的的数值进行转化时,内部使用箱位(clamping)算法,而不是模数(modulo)算法。

ArrayBufferView对象的作用:可以根据同一个ArrayBuffer对象创建各种数值类型的数组。

  • 实例1】在下面实例代码中,根据相同的ArrayBuffer对象,可以创建32位的整数数组和8位的无符号整数数组。
//根据ArrayBuffer对象创建32位整数数组
var array1 = new Int32Array(ArrayBuffer);
//根据同一个ArrayBuffer对象创建8位无符号整数数组
var array2 = new Unit8Array(ArrayBuffer);

在创建ArrayBufferView对象时,除了要指定ArrayBuffer缓存区外,还可以使用下面两个可选参数。

  • byteOffset:为无符号长整型数值,设置开始引用位置与ArrayBuffer缓存区第1个字节之间的偏离值,单位为字节。需要注意的是,属性值必须为数组中单个元素的字节长度的倍数,省略该参数数值时,ArrayBufferView对象将从ArrayBuffer缓存区的第一个字节开始引用。
  • length:为无符号长整数数值,设置数组中的元素的个数。如果省略该参数,将根据缓存区长度、ArrayBufferView对象开始引用的位置、每个元素的字节长度自动计算出元素的个数。

如果设置了byteOffset和length参数值,数组从byteOffset参数值指定的开始位置,长度为length参数值为指定的元素个数*每个元素的字节长度。

如果忽略了byteOffset和length参数值,数组将跨越整个ArrayBuffer缓存区。

如果省略length参数值,数组将从byteOffset参数值指定的开始位置到ArrayBuffer缓存区的结束位置。

ArrayBufferView对象包含以下3个属性。

  • buffer:只读属性,表示ArrayBuffer对象,返回ArrayBufferView对象引用的ArrayBuffer缓存区。

  • byteOffset:只读属性,表示一个无符号长整型数值,返回ArrayBufferView对象开始引用的位置与ArrayBuffer缓存区的第一个字节之间的偏离值,单位为字节。

  • length:只读属性,表示一个无符号长整型数值,返回数组中的元素的个数。

  • 实例2】下面代码演示了如何获取ArrayBuffer缓存区中的数据。

var byte = array2[4];
array2[4] = 1;

使用DataView

除了使用ArrayBufferView子类外,也可以使用DataView子类存取ArrayBuffer缓存区中的数据。DataView继承于ArrayBufferView类,提供了直接存取ArrayBuffer缓存区中的数据的方法。

创建DataView对象的方法如下:

var view = new DataView(buffer, byteOffset, byteLenght);

参数说明如下:

  • buffer:为ArrayBuffer对象,表示一个ArrayBuffer缓存区。
  • byteOffset:可选参数,为无符号长整型数值,表示DataView对象开始引用的位置,与ArrayBuffer缓存区第一个字节之间的偏移值,单位为字节。如果忽略该参数值,将从ArrayBuffer缓存区的第一个字节开始引用。
  • byteLength:可选参数,为无符号长整型数值,表示DataView对象的总字节长度。

如果设置了byteOffset和byteLength参数值,DataView对象从byteOffset参数值所指定的开始位置开始,长度为byteLength参数值所指定的总字节长度。

如果忽略了byteOffer和byteLength参数值,DataView对象将跨越整个ArrayBuffer缓存区。

如果省略byteLength参数值,DataView对象将从byteOffset参数做置顶的开始位置到ArrayBuffer缓存区的结束位置。

DataView对象包含的方法如下表:

方法 说明
getInt8(byteOffset) 获取指定位置的一个8位整数值
getUint8(byteOffset) 获取指定位置的8位无符号型整数值
getInt16(byteOffset,littleEndian) 获取指定位置的一个16位整数值
getUint16(byteOffset,littleEndian) 获取指定位置的一个16位无符号型整数值
getUint32(byteOffset,littleEndian) 获取指定位置的一个32位无符号型整数值
getFloat32(byteOffset,littleEndian) 获取指定位置的一个32位浮点数值
getFloat64(byteOffset,littleEndian) 获取指定位置的一个64位浮点数值
setInt8(byteOffset,value) 设置指定位置的一个8位整数值
setUint8(byteOffset,value) 设置指定位置的一个8位无符号型整数值
setInt16(byteOffset,value,littleEndian) 设置指定位置的一个16位整数数值
setUint16(byteOffset,value,littleEndian) 设置指定位置的一个16位无符号型整数值
setUint32(btyteOffset,value,littleEndian) 设置指定位置的一个32位无符号型整数值
setFloat32(byteOffset,value,littleEndian) 设置指定位置的一个32位浮点数值
setFloat64(byteOffset,value,littleEndian) 设置指定位置的一个64位符点数值
  • 提示:在上述方法中,各个参数说明如下:
    • byteOffset:为一个无符号长整型数值,表示设置或读取整数所在位置在DataView对象对ArrayBuffer缓存区的开始引用位置之间相隔多少个字节。
    • value:为无符号对应类型的数值,表示在指定位置进行设定的整型数值。
    • littleEndian:可选参数,为布尔类型,判断该整型数数值的字节序。当值为true时,表示以little-endian方式设置或读取该整数数值;当参数值为false或忽略参数值时,表示以big-endian方式读取该整数数值。
  • 实例】下面实例演示如何使用DataView对象的相关方法,实现对文件数据进行截取和检测。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test</title>

</head>

<style type="text/css">

</style>

<script>
    window.onload = function() {
     
     
        var result = document.getElementById("result");
        var file = document.getElementById("file");
        if (typeof FileReader == 'undefined') {
     
     
            result.innerHTML = "<h1>当前浏览器不支持FileReader对象</h1>"
            file.setAttribute('disabled', 'disabled');
        }
    }

    function file_onchange() {
     
     
        var file = document.getElementById("file").files[0];
        if (!/image\/\w+/.test(file.type)) {
     
     
            alert("请选择一个图像文件!");
            return;
        }
        var slice = file.slice(0, 4);
        var reader = new FileReader();
        reader.readAsArrayBuffer(slice);
        var type;
        reader.onload = function(e) {
     
     
            var buffer = this.result;
            var view = new DataView(buffer);
            var magic = view.getInt32(0, false);
            if (magic < 0)
                magic = magic + 0x1000000000;
            magic = magic.toString(16).toUpperCase();
            if (magic.indexOf('FFD8FF') >= 0)
                type = "jpg文件";
            if (magic.indexOf('89504E47') >= 0)
                type = "png文件";
            if (magic.indexOf('47494638') >= 0)
                type = "gif文件";
            if (magic.indexOf('49492A00') >= 0)
                type = "tif文件";
            if (magic.indexOf('424D') >= 0)
                type = "bmp文件";
            document.getElementById("result").innerHTML = '文件类型为:' + type;


        }
    }
</script>

<body>
    <input type="file" id="file" onchange="file_onchange()" /><br/>
    <output id="result"></output>

</body>


</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vhzcuefs-1603411823631)(/Users/mac/Desktop/MarkDown /Javascript/js复习笔记/js复习笔记十三 /5.gif)]

  • 设计分析
  1. 在上面实例中,先在页面中设计一个文件控件。
  2. 当用户在浏览器中选取一个图像文件后,js先检测文件类型,当检测为图像文件时,再使用File对象的slice()方法将该文件中前4个字节的内容复制到一个Blob对象中。
  3. 新建FileReader对象,使用该对象的readAsArrayBuffer()方法将Blob对象中的数据读取为一个ArrayBuffer对象。
  4. 读取ArrayBuffer对象后,使用DataView对象读取该ArrayBuffer缓存区中位于开头位置的一个32位整数。
  5. 根据该整数值判断用户选取的文件类型,并将文件类型显示在页面上。

使用FileSystem API

FileSystem API包括两部分内容:一部分内容为除后台线程之外的任何场合都可以使用的异步API,另一部分内容为后台线程中专用的同步API

FileSystem API具有如下特性。

  • 支持跨域通信,但是每个域的文件系统只能被该域专用,不能被其他域访问。
  • 存储的数据是永久的,不能被浏览器随意删除,但是存储在临时文件系统中的数据被浏览器自行删除。
  • 当Web应用连续发出多次对文件系统的操作请求时,每一个请求都将得到相应,同时第1个请求中所保存的数据可以被之后的请求立即得到。

访问FileSystem

使用window对象的requestFileSystem()方法可以请求访问受到浏览器沙箱保护的本地系统。

window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(type, size, successCallback, opt_ errorCallback);

参数说明如下:

  • type:设置请求访问的文件系统使用的文件存储空间的类型,取值包括window.TEMPORARY和window.PERSISTENT。当值为window.TEMPORARY时,表示请求临时的存储空间,存储在临时存储空间中的数据可以被浏览器自行删除;当值为window.PERSISTENT时,表示请求永久存储空间,存储在该空间的数据不能被浏览器在用户不知情的情况下将其清除,只能通过用户或应用程序来清除,请求永久存储空间需要用户为应用程序指定一定的磁盘配额。
  • size:设置请求的文件系统使用的文件存储空间大小,单位为byte。
  • successCallback:设置请求成功时执行的回调函数,该回调函数的参数为一个FileSystem对象,表示请求访问的文件系统对象。
  • opt_errorCallback:可选参数,设置请求失败时执行的回调函数,该回调函数的参数为一个FileError对象,其中存放了请求失败的各种信息。

FileError对象包含code属性,其值为FileSystem API中预定义的常量值,说明如下。

  • FileError.QUOTA_EXCEEDED_ERR:文件系统所使用的的存储空间尺寸超过磁盘配额控制中指定的空间尺寸。

  • FileError.NOT_FOUND_ERR:未找到文件或目录。

  • FileError.SECURITY_ERR:操作不当引起安全问题。

  • FIleError.INVALID_MODIFICATION_ERR:指定的状态无效。

  • FileError.ABORT_ERR:当前操作被终止。

  • FileError.NOT_READABLE_ERR:用户企图访问目录或文件,但是用户访问的目录事实上是一个文件或者用户访问的文件事实上是一个目录。

  • FileError.PATH_EXISTS_ERR:用户指定的路径中不存在需要访问的目录或文件。

  • 实例】下面实例演示如何在Web应用中使用FileSystem API。

<script>
    window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
    var fs = null;
    if (window.requestFileSystem) {
    
    
        window.requestFileSystem(window.TEMPORARY, 1024 * 1024,
            function(filesystem) {
    
    
                fs = filesystem;
            }, errorHandler);
    }

    function errorHandler(FileError) {
    
    
        switch (FileError.code) {
    
    
            case FileError.QUOTA_EXCEEDED_ERR:
                console.log('文件系统的存储空间超过磁盘限制控制中指定的空间尺寸');
                break;
            case FileError.NOT_FOUND_ERR:
                console.log('未找到文件或目录');
                break;
            case FileError.INVALID_MODIFICATION_ERR:
                console.log('对文件或目录所指定的操作不能被执行');
                break;
            case FileError.INVALID_STATE_ERR:
                console.log('指定的状态无效');
        }
    }
</script>

在上面代码中,先判断浏览器是否支持FileSystem API,如果支持则调用window.requestFileSystem()请求访问本地文件系统,如果请求失败则在控制台系那是错误信息。

创建文件

创建文件的操作思路:当用户调用requestFileSystem()方法请求访问本地文件系统时,如果请求成功,则执行一个回调函数,这个回调函数中包含一个参数,它指向可以获取的文件系统对象,该文件系统对象包含一个root属性,属性值为一个DirectoryEntry对象,表示文件系统的根目录对象。在请求成功时执行的回调函数中,可以通过文件系统的根目录对象的getFile()方法在根目录中创建文件。

getFile()方法包含4个参数,简单说明如下:

  • 第一个参数:为字符串值,表示需要创建或获取的文件名。
  • 第二个参数:为一个自定义对象。当创建文件时,必须将该该对象的create属性值设置为true;当获取文件时,必须将该对象的create属性值设置为false;当创建文件时,如果该文件已存在,则覆盖该文件;当读取文件时,如果该文件已存在,且被使用排他方式打开,则抛出错误。
  • 第三个参数:为一个函数,代表获取文件或创建文件成功时执行的回调函数。在回调函数中可以使用一个参数,参数值为一个FileEntry对象,表示成功创建或获取的文件。
  • 第四个参数:为一个函数,代表获取文件或创建文件失败时的各种错误信息。

FileError对象表示收到沙箱保护的文件系统中的每一个文件。该对象包含如下属性。

  • isFile:区分对象是否为文件。属性值为true,表示对象为文件;属性值为false,表示该对象为目录。
  • isDirectory:区分对象是否为目录。属性值为true,表示对象为目录;属性值为false,表示该对象为文件。
  • name:表示该文件的文件名,包括文件的扩展名。
  • fullPath:表示该文家你的完整路径。
  • filesystem:表示该文件所在的文件系统对象。

另外,FIleEntry对象包括remove()(删除)、moveTo()(移动)、copyTo(拷贝)等方法。

  • 实例】下面实例演示了床架文件的基本方法。在页面中设计两个文本框和一个“创建文件”按钮,其中一个文本框控件用于输入文件名,另一个文本框用于输入文件大小,单位为byte,用户输入文件名及文件大小后,单击“创建文件”按钮,js会在文件系统中的根目录下创建文件,并将创建的文件信息显示在页面中。
<script>
    window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;

    function createFile() {
    
    
        var size = document.getElementById("FileSize").value;
        window.requestFileSystem(PERSISTENT, size,
            function(fs) {
    
    
                var filename = document.getElementById("FileName").value;
                fs.root.getFile(
                    filename, {
    
    
                        create: ture
                    },
                    function(fileEntry) {
    
    
                        var text = "完整路径:" + fileEntry.fullPath + "<br>";
                        text += "文件名:" + fileEntry.name + "<br>";
                        document.getElementById("result").innerHTML = text;
                    },
                    errorHandler
                );
            },
            errorHandler
        );
    }

    function errorHandler(FileError) {
    
    
        switch (FileError.code) {
    
    
            case FileError.QUOTA_EXCEEDED_ERR:
                console.log('文件系统的存储空间超过磁盘限制控制中指定的空间尺寸');
                break;
            case FileError.NOT_FOUND_ERR:
                console.log('未找到文件或目录');
                break;
            case FileError.INVALID_MODIFICATION_ERR:
                console.log('对文件或目录所指定的操作不能被执行');
                break;
            case FileError.INVALID_STATE_ERR:
                console.log('指定的状态无效');
        }
    }
</script>

<body>
    <h1>创建文件</h1>
    文件名:<input type="text" id="FileName" value="test.txt"><br><br> 文件大小:
    <input type="text" id="FileSize" value="1024">Bytes<br><br>
    <input type="button" value="创建文件" onclick="createFile()"><br><br>
    <output id="result"></output>
</body>

写入数据

HTML5使用FileWriter和FileWriterSync对象执行文件写入操作,其中FileWriterSync对象用于在后台线程中进行文件的写操作,FileWriter对象用于除后台线程之外任何场合进行写操作。

在FileSystem API中,当使用DirectoryEntry对象的getFile()方法成功获取一个文件对象之后,可以在获取文件对象成功时所执行的回调函数中,利用文件对象的createWriter()方法创建FileWriter对象。

createWriter()方法包含两个参数,分别为创建FileWriter对象成功时执行的回调函数和失败时执行的回调函数。在创建FileWriter对象成功时执行的回调函数中,包含一个参数,它表示FileWriter对象。

使用FileWrtier对象的write()方法在获取到文件中写入二进制数据。用法如下:

fileWriter.write(data);

参数data为一个Blob对象,表示要写入的二进制数据。

使用FileWriter对象的writeend和error事件可以进行监听,在事件回调函数中可以使用一个对象,它表示被触发的事件对象。

添加数据

项文件添加数据与创建文件并写入数据操作类似,区别在于获取文件后,首先使用FileWriter对象的seek()方法将文件读写位置设置到文件底部。用法如下

fileWriter.seek(fileWriter.length);

参数值为长整型数值。当值为正值时,表示文件读写位置与文件开头开头处的距离,单位为byte;当值为负值时,表示文件读写位置与文件结尾处之间的距离。

读取数据

在FileSystem API中,使用FileReader对象可以读取文件。

在文件对象(FileEntry)的file()方法中包含两个参数,分别表示获取文件成功和失败的执行的回调函数,在获取文件成功时执行的回调函数中,可以设置一个参数,代表成功获取的文件。

复制文件

在FileSystem API中,可以使用File对象引用磁盘文件,然后将其写入文件系统。用法如下:

fileWriter.write(file);

参数file表示用户磁盘上的一个文件对象;也可以为一个Blob对象,表示需要写入的二进制数据,在HTML5,File对象继承Blob对象,所以在write()方法中可以使用File对象作为参数,表示使用某个文件中的原始数据进行写文件操作。

删除文件

在FileSystem API中,使用FileEntry对象的remove()方法可以删除该文件。remove()方法包含两个参数,被别为删除文件成功和失败时执行的回调函数。

猜你喜欢

转载自blog.csdn.net/weixin_46351593/article/details/109234723