李钊
李钊
  • 发布:2020-08-20 10:31
  • 更新:2023-10-25 17:10
  • 阅读:10593

uniapp中拿到base64转blob对象,或base64转bytes字节数组,io操作写入字节流文件bytes

分类:uni-app

**1. uniAPP中拿到附件的base64如何操作,如word文件

/**

  • 实现思路:
  • 通过native.js的io操作创建文件,拿到平台绝对路径
  • 再通过原生类进行base64解码,拿到字节流bytes数组
  • 在通过java类FileOutputStream进行文件写入bytes返回文件路径path
  • 在通过plus.runtime.openFile(path);用第三方程序打开文件
  • */**
    //文件的写入操作传入要写入文件名,base64  
    function lzFileWriter(base64,fileName) {  
    return new Promise((result,reject)=>{  
        // PRIVATE_WWW:本地文件系统常量,Number类型,固定值1。应用运行资源目录,仅本应用可访问。 为了确保应用资源的安全性,此目录只可读。  
        // PRIVATE_DOC 本地文件系统常量,Number类型,固定值2。应用私有文档目录,仅本应用可读写。  
        plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {  
            /*  
            fs.root是根目录操作对象DirectoryEntry  
            getFile(path,flag,succesCB,errorCB)创建或打开文件  
                path: ( DOMString ) 必选 要操作文件相对于当前目录的地址  
                flag: ( Flags ) 可选 要操作文件或目录的参数 create: (Boolean 类型 )是否创建对象标记 指示如果文件或目录不存在时是否进行创建,默认值为false  
                succesCB: ( EntrySuccessCallback ) 可选 创建或打开文件成功的回调函数  
                errorCB: ( FileErrorCallback ) 可选 创建或打开文件失败的回调函数  
            */  
           // 创建或打开文件  
            fs.root.getFile(fileName,{create:true},function(fileEntry) {  
                // 获得平台绝对路径     
                var fullPath = fileEntry.fullPath;   
                console.log('平台绝对路径',fullPath);  
                // 引入安卓原生类  
                var Base64 = plus.android.importClass("android.util.Base64");  
                var FileOutputStream = plus.android.importClass("java.io.FileOutputStream");  
                //如果文件不存在则创建文件,如果文件存在则删除文件后重新创建文件  
                var out = new FileOutputStream(fullPath);  
                /**  
                 * 此处需要把base64前缀去除,在写入字节流数组  
                 * 去除头部data:image/jpg;base64,留下base64编码后的字符串  
                **/  
                let index=base64.indexOf(',')  
                let base64Str=base64.slice(index+1,base64.length)  
                console.log(base64Str.slice(0,55));  
                //base64解密得到字节流bytes;    
                var bytes = Base64.decode(base64Str,0);  
                try{   
                    console.log(bytes);  
                    out.write(bytes); // byte 数组写入此文件输出流中。  
                    out.flush(); //刷新写入文件中去。  
                    out.close(); //关闭此文件输出流并释放与此流有关的所有系统资源。  
                    result(fullPath)  
                }catch(e){   
                    console.log(e.message);   
                    reject(e.message)  
                }  
                // 下面的方法只能写入字符串,无法写入字节流bytes  
                // fileEntry文件系统中的文件对象,用于管理特定的本地文件  
                // fileEntry.file(function(file) {  
                //  /*createWriter获取文件关联的写文件操作对象FileWriter  
                //      abort: 终止文件写入操作  
                //      seek: 定位文件操作位置  
                //      truncate: 按照指定长度截断文件  
                //      write: 向文件中写入数据  
                //  */  
                //  fileEntry.createWriter(function(FileWriter) {  
                //      FileWriter.write(base64);  
                //      FileWriter.onwriteend=function(res){  
                //          console.log(res.target.fileName);  
                //          result(res.target.fileName)  
                //      }  
                //      FileWriter.onerror=function(error){  
                //          console.log(error);  
                //          reject(error)  
                //      }  
                //  }, function(e) {  
                //      console.log(e);  
                //  });  
                // });  
            });  
        });  
    })  
    }

    2.拿到视频,音频,图片的base64如何操作?

/**

  • 实现思路:
  • 视频和音频拿到base64,可通过h5方式将base64转成blob对象
  • 再通过URL.createObjectURL(blob)生成指向File对象或Blob对象的URL,
  • 此url可以放到大部分标签下的src中进行渲染,如img,video,audio
  • */
    第一步:新建一个vue页面传入base64,创建webview

    create(){  
                let that=this  
                var currentWebview = this.$scope.$getAppWebview()  
                //创建Webview窗口,用于加载新的HTML页面,可通过styles设置Webview窗口的样式,创建完成后需要调用show方法才能将Webview窗口显示出来。  
                let wv = plus.webview.create("/hybrid/html/pages/filePlay.html","/hybrid/html/pages/filePlay.html",{  
                    'uni-app': 'none', //不加载uni-app渲染层框架,避免样式冲突  
                    top: 0,  
                    height: '100%',  
                    background: 'transparent'  
                },{  
                    base64:that.base64,//传参  
                    type:that.type//文件类型  
                });  
                // 在Webview窗口中添加子窗口// ${that}.bbb(objecturl)  
                currentWebview.append(wv);  
            },

    第二步:在filePlay.html中拿到base64

    <!DOCTYPE html>  
    <html>  
    <head>  
        <meta charset="utf-8" />  
        <meta name="viewport" content="width=device-width, initial-scale=1">  
        <title>文件播放系统</title>  
        <style type="text/css">  
            html,  
            body {  
                padding: 0;  
                margin: 0;  
            }  
    
            #App {  
                background: transparent;  
                width: 100vw;  
                height: 100vh;  
                display: flex;  
                flex-direction: column;  
            }  
    
            #App .video {  
                width: 100%;  
                height: 100%;  
            }  
    
            #App .audio {  
                margin: auto;  
            }  
        </style>  
    </head>  
    <body>  
        <div id="App">  
            <video :src="videoSrc" autoplay v-if="videoSrc" controls class="video"></video>  
            <!-- <img :src="imgSrc" v-if="imgSrc"/> -->  
            <audio id="myAudio" controls v-if="audioSrc" class="audio">  
                <source :src="audioSrc" type="audio/ogg">  
                <source :src="audioSrc" type="audio/mpeg">  
                暂不支持播放此类型  
            </audio>  
            <iframe :src='wordSrc' width='100%' height='100%' frameborder='1' v-if="wordSrc"></iframe>  
        </div>  
        <!-- uni 的 SDK -->  
        <script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>  
        <script type="text/javascript" src="../js/vue.js"></script>  
        <script type="text/javascript" src="../js/global.js"></script>  
        <script type="text/javascript" src="../js/file-saver/dist/FileSaver.js"></script>  
        <!-- <script type="text/javascript" src="../js/wps/web-office-sdk-v1.1.2.umd.js"></script> -->  
        <script type="text/javascript">  
            // import { saveAs } from '../js/file-saver/dist/FileSaver.js';  
            document.addEventListener('UniAppJSBridgeReady', function() {  
                let that  
                //webview传参到html5网页  
                let {  
                    base64,  
                    type  
                } = plus.webview.currentWebview();  
                console.log(base64.slice(0, 50));  
                new Vue({  
                    el: '#App',  
                    data: {  
                        videoSrc: '',  
                        imgSrc: '',  
                        audioSrc: '',  
                        wordSrc: '',  
                        aHref: ""  
                    },  
                    async mounted() {  
                        that = this  
                        let blob = that.dataURLtoBlob(base64)  
                        /**  
                         *  URL对象用于生成指向File对象或Blob对象的URL。  
                         * 这个URL可以放置于任何通常可以放置URL的地方,比如img标签的src属性  
                         **/  
                        var blobUrl = URL.createObjectURL(blob);  
                        console.log(blobUrl);  
                        console.log(type);  
                        if (type == 'video') {  
                            that.videoSrc = blobUrl  
                        } else if (type == 'audio') {  
                            that.audioSrc = blobUrl  
                        } else if (type == 'word') {  
                        }  
                        // 在每次调用createObjectURL()方法时,都会创建一个新的URL对象,即使你已经用相同的对象作为参数创建过。当不再需要这些URL对象时,每个对象必须通过调用URL.revokeObjectURL()方法来释放  
                        setTimeout(() => {  
                            window.URL.revokeObjectURL(objecturl); //释放createObjectURL创建得对象  
                        }, 2000)  
    
                    },  
                    methods: {  
                        //base64转成blob对象第一种方式  
                        dataURLtoBlob(dataurl) {  
                            var arr = dataurl.split(','),  
                                mime = arr[0].match(/:(.*?);/)[1],  
                                bstr = atob(arr[1]),  
                                n = bstr.length,  
                                u8arr = new Uint8Array(n);//8位无符号整数,长度1个字节  
                            console.log(mime)  
                            while (n--) {  
                                u8arr[n] = bstr.charCodeAt(n);  
                            }  
                            // console.log(JSON.stringify(u8arr));  
                            return new Blob([u8arr], {  
                                type: mime  
                            });  
                        },  
    
                    }  
                })  
            });  
        </script>  
    </body>  
    </html>
3 关注 分享
艺术派大星 E***@foxmail.com Meaty

要回复文章请先登录注册

krisign

krisign

回复 2***@qq.com :
我用这种方式确实解决了我的问题:

plus.io.requestFileSystem(plus.io.PUBLIC_DOWNLOADS, function(fs) {
fs.root.getFile(res.fileName+"",{create:true},function(fileEntry) {
console.log(fileEntry.fullPath);
fileEntry.createWriter(function(writer) {

writer.onwriteend = function(result){
console.log("write end"+result);

plus.nativeUI.closeWaiting();
var filePath = fileEntry.fullPath.substr(0, fileEntry.fullPath.lastIndexOf("."));
plus.nativeUI.confirm("Download success, do you want to open this file?",function(e){
var index = e.index;
if (index == 0) {
plus.runtime.openFile(fileEntry.fullPath);
}
},{"title":"Attachment",
"buttons":["Yes","No"],
"verticalAlign":"center"
});

};

writer.seek(0);
writer.writeAsBinary(fileBase64);
writer.abort();

})
},function(err) {
console.log("failed:"+err);
plus.nativeUI.closeWaiting();
})
}, function(err) {
console.log(err)
plus.nativeUI.closeWaiting();
});
2023-10-25 17:10
1***@qq.com

1***@qq.com

回复 2***@qq.com :
太牛了
2023-05-09 16:21
百倍

百倍

回复 qvqv123 :
你看看我发的这篇文章https://blog.csdn.net/qq285679784/article/details/126838827
2023-03-06 17:25
qvqv123

qvqv123

回复 百倍 :
try catch 那里报undefined怎么解决
2023-02-27 16:14
2***@qq.com

2***@qq.com

给你们来个简单的,官方的,只是没有公布出来。
uniapp 流文件的写入,先转为base64,再写入

fileEntry.createWriter(function(write){
writer.seek(0);
//此处的base64不含 文件的头信息,不能有\r\n. 相当于不能通过 readAsBase64来获取,或者自行替换。
writer.writeAsBinary(base64Str);
writer.abort();
})

官方还有没公布的,可能有用的 “readAsBase64”,不过跟readAsDataURL差不多,只是 readAsBase64出来的没有文件头,且有\r\n。
其他的,自己看android源码。
2022-11-25 17:16
我愿你知道

我愿你知道

回复 百倍 :
哈哈哈 后面我搜到了
2022-10-17 11:32
百倍

百倍

回复 我愿你知道 :
解决了,并且功能已经上线,源码在这里:https://blog.csdn.net/qq285679784/article/details/126838827
2022-10-13 16:25
我愿你知道

我愿你知道

回复 百倍 :
请问你解决了吗?我也遇到这个问题了
2022-10-12 10:33
百倍

百倍

lzFileWriter这个方法,iOS端怎么实现?
2022-09-13 10:15
Chroisen

Chroisen

请问这个blob怎么保存呢?
2022-01-24 13:12