沙箱(沙盒)
HTML5提供了关于文件操作的文件API,其中FileSystem API就是可以存取受浏览器沙箱保护的文件系统。使用FileSystem API,应用程序将得到一个受保护的文件系统,该文件系统中保存的数据可以永久保存在客户端计算机中,而且这些被保存的数据只有通过用户执行删除数据功能才能将这些数据删除。
先了解一下ArrayBuffer对象和ArrayBufferView对象
ArrayBuffer对象代表一个存储固定长度的二进制数据的缓存区。不能直接存取ArrayBuffer缓存区中的内容,必须通过ArrayBufferView对象来读写ArrayBffer缓存区中的内容。
在HTML5中,通过如下所示的方法创建ArrayBuffer对象
var buf = new ArrayBuffer(32)
在创建ArrayBuffer对象时,需要使用一个无符号长整数类型的参数,用于指定缓存区的长度,单位为byte,在成功创建后,该缓存区中的所有数据都被初始化为0。ArrayBuffer对象具有一个length属性,属性值为缓存区长度。
在HTML5中一般不直接使用ArrayBufferView对象,而是使用继承ArrayBufferView类的子类的实例对象来存取ArrayBuffer缓存区中的数据。
下面表格是继承ArrayBufferView类的各种子类
类型 | 字节长度 | 描述 |
---|---|---|
Int8Array | 1 | 8位整数数组 |
Uint8Array | 1 | 8位无符号整数数组 |
Uint8ClampedArray | 1 | 8位整数数组 |
Int16Array | 2 | 16位整数数组 |
Uint8Array | 2 | 16位无符号整数数组 |
Int32Array | 4 | 32位整数数组 |
Uint32Array | 4 | 32位无符号整数数组 |
Float32Array | 4 | 32位IEEE浮点数数组 |
Float64Array | 8 | 64位IEEE浮点数数组 |
ArrayBufferView对象的作用在于:可以根据同一个ArrayBuffer对象来创建各种数值类型的数组,例如:
// 根据ArrayBuffer对象创建32位整数数组
var int32Array = new Int32Array(ArrayBuffer)
// 根据同一个ArrayBuffer对象创建8位无符号整数数组
var uInt8Array = new Uint8Array(ArrayBuffer)
Blob对象
在HTML5中,新增了一个Blob对象,代表原始二进制数据。事实上,file对象也继承了这个Blob对象。Blob对象有两个属性,size属性表示一个Blob对象的字节长度,type属性表示Blob的MIME类型,如果是未知类型,则返回一个空字符串。
Blob对象的type属性可以判定是什么类型文件,size可以知道文件长度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="file" id="file">
<input type="button" value="显示文件信息" onclick="showFileType()"><br/>
文件类型长度:<span id="size"></span><br/>
文件类型: <span id="type"></span>
</body>
<script>
function showFileType(){
var file
file = document.getElementById('file').files[0]
var size = document.getElementById('size')
var type = document.getElementById('type')
type.innerHTML = file.type
size.innerHTML = file.size
}
</script>
</html>
创建及下载二进制文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<textarea id="text" placeholder="请输入文字"></textarea><br/>
<button id="btn" onclick="blob_test()">创建及下载二进制文件</button>
<output id="result"></output>
</body>
<script>
function blob_test(){
const text = document.getElementById('text')
var blob
const result = document.getElementById('result')
if(!window.Blob) result.innerHTML = '你的浏览器不支持使用Blob对象'
else
blob = new Blob([text])
if(window.URL){
result.innerHTML = `<a download href="' + window.URL.createObjectURL(blob)+'" target="_blank">文件下载</a>`
}
}
</script>
</html>
FileSystem API
在HTML5中新增了 FileSystem API,使用该API,用户可以将数据保存在磁盘上的文件系统中,从而得到一个永久保存数据的空间。
文件上传:
当用户通过FileSystem API上传文件系统中的文件或目录时,这些文件将首先被拷贝到本地沙箱中,然后分段上传本地沙箱中的文件,每次上传其中的一部分。因此,当上传操作因浏览器崩溃或网络中断原因终止时,下次也可以继续上传上一次未被上传的部分。
请求访问文件系统
在html5中,Web网站可以通过调用浏览器窗口对象的requestFileSystem方法来请求访问受到浏览器沙箱保护的本地文件系统。
window.requestFileSystem = window.requestFileSystem||window.webkitRequestFileSystem
window.requestFileSystem(type,size,successCallback,opt_errorCallback)
type:指定所请求访问的文件系统所使用的文件存储空间的类型;window.TEMPORARY时为临时存储空间,window.PERSISTENT时为永久存储空间
size:指定所请求文件系统所使用的文件存储空间的大小(尺寸为byte)
successCallback:请求成功时执行的回调,该回调函数的参数是一个FileSystem对象,代表请求访问的文件系统对象
opt_errorCallback:可选参数,用于指定请求失败时执行的回调函数,该回调函数的参数是一个FileError对象,其中存放了请求失败时的各种失败信息。
请求访问文件系统
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>请求访问文件系统</title>
</head>
<body>
<output id="result"></output>
</body>
<script>
window.requestFileSystem = window.requestFileSystem||window.webkitRequestFileSystem
var fs = null
if(window.requestFileSystem){
initFs()
}
function initFs(){
window.requestFileSystem(window.TEMPORARY,1024*1024,function(filesystem){
fs = filesystem
},errorHandle)
}
function errorHandle(e){
var msg = ''
switch(e.code){
case FileError.QUOTA_EXCEEDED_ERR:
msg = '文件系统所使用的存储空间的尺寸超过磁盘限额控制中指定的空间尺寸';
break;
case FileError.NOT_FOUND_ERR:
msg = '未找到文件或目录';
break;
case FileError.SECURITY_ERR:
msg = '操作不当引起安全性错误';
break;
}
document.getElementById('result').innerHTML = '当前操作引发错误'+msg
}
</script>
</html>
申请磁盘配额
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>申请磁盘配额</title>
</head>
<body>
<form>
<input type="text" id="capacity" value="1024">
<input type="button" value="申请磁盘配额" onclick="getQuota()">
</form>
<output id="result"></output>
</body>
<script>
// 申请磁盘配额
function getQuota(){
var size = document.getElementById('capacity').value
window.webkitStorageInfo.requestQuota(PERSISTENT,size,
// 申请磁盘成功的回调
function(grantedBytes){
var text = '申请磁盘配额成功<br>磁盘配额尺寸:'
var strBytes,intBytes
if(grantedBytes>=1024*1024*1024){
intBytes = Math.floor(grantedBytes/(1024*1024*1024))
text+=intBytes+'GB'
grantedBytes = grantedBytes%(1024*1024*1024)
}
if(grantedBytes>=1024*1024){
intBytes = Math.floor(grantedBytes/(1024*1024))
text+=intBytes+'MB'
grantedBytes = grantedBytes%(1024*1024)
}
if(grantedBytes>=1024){
intBytes = Math.floor(grantedBytes/1024)
text+=intBytes+'KB'
grantedBytes=grantedBytes%1024
}
text+=grantedBytes+'Bytes'
document.getElementById('result').innerHTML = text
},errorHandle)
}
// 错误回调
function errorHandle(e){
var msg = ''
switch(e.code){
case FileError.QUOTA_EXCEEDED_ERR:
msg = '文件系统所使用的存储空间的尺寸超过磁盘限额控制中指定的空间尺寸';
break;
case FileError.NOT_FOUND_ERR:
msg = '未找到文件或目录';
break;
case FileError.SECURITY_ERR:
msg = '操作不当引起安全性错误';
break;
}
document.getElementById('result').innerHTML = '当前操作引发错误'+msg
}
</script>
</html>
成功申请磁盘配额之后,可以使用window.webkitStorageInfo.queryUsageAndQuota方法查询申请的磁盘配额信息
window.webkitStorageInfo.queryUsageAndQuota(PERSISTENT,function(usage,quota){},errorHandle)
创建目录 (fs.root.getDirectory)
function createDirectory(){
window.webkitRequestFileSystem(PERSISTENT,1024,
// 创建目录
function(fs){
var directoryName = document.getElementById('directoryName').value
fs.root.getDirectory(directoryName,{create:true},
// 创建成功的回调
function(dirEntry){
console.log(dirEntry)
var res = "目录完整路径:"+dirEntry.fullPath+"<br/>"
res += "目录名:"+dirEntry.name+"<br>"
document.getElementById("direResult").innerHTML = res
})
},errorHandle)
}
创建文件 (fs.root.getFile)
在HTML5中,使用FileEntry对象来表示受到沙箱保护的文件系统中的每一个文件。与普通文件系统中的文件一样,每一个FileEnry对象都拥有name、fullpath、remove、moveTo、copyTo等方法
在受到沙箱保护的文件系统中创建一个文件
function createFile(){
window.webkitRequestFileSystem(PERSISTENT,1024,
// 创建目录
function(fs){
var fileName= document.getElementById('fileName').value
fs.root.getFile(fileName,{create:true},
// 创建成功的回调
function(fileEntry){
console.log(fileEntry)
var res = "文件完整路径:"+fileEntry.fullPath+"<br/>"
res += "文件名:"+fileEntry.name+"<br>"
document.getElementById("fileResult").innerHTML = res
})
},errorHandle)
}
在指定目录中存储文件
首先使用fs.root.getDirectory()方法来获取指定的目录,然后dirEntry.getFile()方法在mydir目录中创建文件myfile.txt,然后使用fileEntry.createWriter()方法来创建文件写入器,最后使用fileWriter.write()方法将数据写入文件。
fs.root.getDirectory('mydir',{create:true},function(dirEntry){
// 在mydir目录中创建myfile.txt文件
dirEntry.getFile('myfile.txt',{create:true,exclusive:false},
// 创建文件写入器
function(fileEntry){
fileEntry.createWriter(function(fileWriter){
fileWriter.onwriteend = function(e){
console.log('文件已经成功写入')
}
fileWriter.onerror = function(e){
console.log('文件写入失败'+e.tostring())
}
// 写入文件
var text = new Blob(['hello world'],[type:'text/plain'])
fileWriter.write(text)
},errorHandle)
},errorHandle)
},errorHandle)
读取目录或文件、删除目录或文件、复制目录或文件、移动目录或文件、重命名目录或文件等就不一一写啦~~~~~~~~~~
THE END