zoukankan      html  css  js  c++  java
  • File System 定额(配额查询)

    不多说,在弄一个基于FileSytem/IndexedDB的小应用,目前处于基础开发阶段,

    我们在使用FileSystem的时候无疑是需要知道浏览器的定额(配额的),怎么去查询,当然可以查询 Quota Management API

    个人觉得还是略有复杂,为了避免不停的then,同时更少的关注内部的区别,再简单包装了一下。

    不多说,代码:

    /**
     * 参考的API:
     * http://w3c.github.io/quota-api/
     * 
     */
    
    
    //文件系统请求标识 
    window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem
    //根据URL取得文件的读取权限 
    window.resolveLocalFileSystemURL = window.resolveLocalFileSystemURL || window.webkitResolveLocalFileSystemURL
    
    //临时储存和永久存储
    navigator.temporaryStorage = navigator.temporaryStorage || navigator.webkitTemporaryStorage;
    navigator.persistentStorage = navigator.persistentStorage || navigator.webkitPersistentStorage;
    
    //常量
    const _TEMPORARY = 'temporary', _PERSISTENT = 'persistent'
    
    /**
     * 转为promise,主要是把 a.b(param1,param2,successCallback,errorCall) 转为promise
     * @param {*期待的是函数} obj 
     * @param {*上下文} ctx 
     * @param {*参数} args 
     */
    function toPromise(obj, ctx, ...args) {
        if (!obj) return obj
    
        //如果已经是Promise对象
        if ('function' == typeof obj.then) return obj
    
        //若obj是函数直接转换
        if ('function' == typeof obj) return _toPromise(obj)
    
        return obj;
    
        //函数转成 promise
        function _toPromise(fn) {
            return new Promise(function (resolve, reject) {
    
                fn.call(ctx, ...args, (...ags) => {
                    //多个参数返回数组,单个直接返回对象
                    resolve(ags && ags.length > 1 ? ags : ags[0])
                }, (err) => {
                    reject(err)
                })
    
            })
        }
    }
    
    
    
    /**
     * 查询和申请定额
     * 测试脚本:
     * 使用情况: FileStorageQuota.instance.queryInfo().then(data=>console.log(data))
     * 申请空间: FileStorageQuota.instance.requestPersistentQuota().then(data=>console.log(data))
     */
    class FileStorageQuota {
    
        constructor() {
    
            let supportedTypes = [_TEMPORARY, _PERSISTENT];
    
            this.storageQuota = navigator.storageQuota || {
                storages: { [_TEMPORARY]: navigator.webkitTemporaryStorage, [_PERSISTENT]: navigator.webkitPersistentStorage },
                queryInfo: function (type) {
                    return toPromise(this.storages[type].queryUsageAndQuota, this.storages[type]).then(arr => {
                        return { usage: arr[0], quota: arr[1] }
                    })
                },
                requestPersistentQuota: function (requestQuota) {
                    return toPromise(this.storages[_PERSISTENT].requestQuota, this.storages[_PERSISTENT], requestQuota * 1024 * 1024).then(quota => {
                        return { quota }
                    })
                },
                supportedTypes
            }
            this.supportedTypes = supportedTypes
            this._instance = null //实例
        }
    
        /**
         * 获得实例
         */
        static get instance() {
            return !!this._instance ? this._instance : this._instance = new FileStorageQuota()
        }
    
        /**
         * 已经分配的额度和适用查询
         * @param {*类型  window.TEMPORAR(0) |window.PERSISTENT(1) }  type
         */
        queryInfo(type = window.TEMPORARY) {
    
            return new Promise((resolve, reject) => {
                this.storageQuota.queryInfo(this.supportedTypes[type])
                    .then(storageInfo => resolve({ quota: this.tansferBytes(storageInfo.quota), usage: this.tansferBytes(storageInfo.usage) }))
                    .catch(this.errorHandler(reject))
            })
    
        }
    
        /**
         * 请求配额,只有PERSISTENT才需要用户允许,
         * 返回值是你请求的和已经分配的大值
         * @param {* window.TEMPORAR(0) |window.PERSISTENT(1)} type
         * @param {* 请求的配额大小} requestQuota  
         */
        async requestPersistentQuota(requestQuota = 5) {
            let { quota: quotaM, usage } = await this.queryInfo(window.PERSISTENT)
            if (requestQuota > quotaM) {
                return new Promise((resolve, reject) =>
                    this.storageQuota.requestPersistentQuota(requestQuota * 1024 * 1024)
                        .then(storageInfo => {
                            return resolve({ quota: this.tansferBytes(storageInfo.quota), usage: this.tansferBytes(storageInfo.usage || usage) })
                        })
                        .catch(this.errorHandler(reject)))
            }
            return { quota: Math.max(requestQuota, quotaM), usage }
        }
    
        /**
         * 把bytes换算成KB,M,G等
         * @param {* bytes的长度}  bytesLength
         * @param {* 转为目标的单位} target
         */
        tansferBytes(bytesLength, target = 'M') {
            let m = {
                'Byte': 0,
                'KB': 1,
                'M': 2,
                'G': 3
            }
            return bytesLength / Math.pow(1024, m[target] || 0)
        }
    
        /**
         * Promise里面的错误处理
         * @param {*}  reject
         */
        errorHandler(reject) {
            return (error) => {
                reject(error)
            }
        }
    }

    测试:

    FileStorageQuota.instance.queryInfo().then(data=>console.log(data))
    
    Object {quota: 2767.7421379089355, usage: 22.347068786621094}
    

      

    FileStorageQuota.instance.requestPersistentQuota().then(data=>console.log(data))
    
    Object {quota: 10240, usage: 0}

    源码地址:https://github.com/xiangwenhu/BlogCodes/tree/master/client/FileSystem 

    参考:

     Quota Management API

    StorageQuota - Web APIs | MDN

  • 相关阅读:
    UVA 11235 (游程编码+ST算法)
    CodeForces 359D (数论+二分+ST算法)
    线性动态规划
    AC自动机
    KMP
    字典树
    Treap和名次树
    线段树
    最小生成树
    【VS】使用vs2017自带的诊断工具(Diagnostic Tools)诊断程序的内存问题
  • 原文地址:https://www.cnblogs.com/cloud-/p/6773215.html
Copyright © 2011-2022 走看看