uni-app中实现base64转blob对象或base64转bytes字节数组,并进行io操作写入字节流文件bytes

发布于 1周前 作者 yibo5220 来自 Uni-App

uni-app中实现base64转blob对象或base64转bytes字节数组,并进行io操作写入字节流文件bytes

uniAPP中拿到附件的base64如何操作

1. 处理Word文件

实现思路:

  • 通过native.js的IO操作创建文件,拿到平台绝对路径
  • 再通过原生类进行base64解码,拿到字节流bytes数组
  • 在通过java类FileOutputStream进行文件写入bytes返回文件路径path
  • 在通过plus.runtime.openFile(path);用第三方程序打开文件
// 文件的写入操作传入要写入文件名,base64  
function lzFileWriter(base64, fileName) {  
    return new Promise((result, reject) => {
        plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {  
            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);  
                let index = base64.indexOf(',');  
                let base64Str = base64.slice(index + 1, base64.length);  
                console.log(base64Str.slice(0, 55));  
                var bytes = Base64.decode(base64Str, 0);  
                try {   
                    console.log(bytes);  
                    out.write(bytes);  
                    out.flush();  
                    out.close();  
                    result(fullPath);  
                } catch (e) {   
                    console.log(e.message);   
                    reject(e.message);  
                }  
            });  
        });  
    });  
}

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();  
    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 // 文件类型  
    });  
    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>
        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>  
        <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>  
    <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">  
        document.addEventListener('UniAppJSBridgeReady', function() {  
            let { base64, type } = plus.webview.currentWebview();  
            console.log(base64.slice(0, 50));  
            new Vue({  
                el: '#App',  
                data: {  
                    videoSrc: '',  
                    imgSrc: '',  
                    audioSrc: '',  
                    wordSrc: '',  
                    aHref: ""  
                },  
                async mounted() {  
                    let blob = this.dataURLtoBlob(base64);  
                    var blobUrl = URL.createObjectURL(blob);  
                    console.log(blobUrl);  
                    console.log(type);  
                    if (type == 'video') {  
                        this.videoSrc = blobUrl;  
                    } else if (type == 'audio') {  
                        this.audioSrc = blobUrl;  
                    } else if (type == 'word') {  
                    }  
                    setTimeout(() => {  
                        window.URL.revokeObjectURL(objecturl); // 释放createObjectURL创建得对象  
                    }, 2000);  
                },  
                methods: {  
                    dataURLtoBlob(dataurl) {  
                        var arr = dataurl.split(',');  
                        var mime = arr[0].match(/:(.*?);/)[1];  
                        var bstr = atob(arr[1]);  
                        var n = bstr.length;  
                        var u8arr = new Uint8Array(n);  
                        while (n--) {  
                            u8arr[n] = bstr.charCodeAt(n);  
                        }  
                        return new Blob([u8arr], { type: mime });  
                    }  
                }  
            });  
        });  
    </script>  
</body>  
</html>
开发环境 版本号 项目创建方式
HBuilderX 3.1.17+ 使用uni-app模板创建

1 回复

在uni-app中,你可以使用JavaScript来实现base64转blob对象或base64转bytes字节数组,并进行I/O操作将字节流写入文件。以下是如何实现这些功能的代码案例:

1. Base64 转 Blob 对象

首先,将Base64字符串转换为Blob对象:

function base64ToBlob(base64Data, contentType = 'application/octet-stream', sliceSize = 512) {
    const byteCharacters = atob(base64Data);
    const byteArrays = [];

    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        const slice = byteCharacters.slice(offset, offset + sliceSize);
        const byteNumbers = new Array(slice.length);
        for (let i = 0; i < slice.length; i++) {
            byteNumbers[i] = slice.charCodeAt(i);
        }
        const byteArray = new Uint8Array(byteNumbers);
        byteArrays.push(byteArray);
    }

    const blob = new Blob(byteArrays, { type: contentType });
    return blob;
}

2. Base64 转 Bytes 字节数组

将Base64字符串转换为Uint8Array(字节数组):

function base64ToBytes(base64Data) {
    const binaryString = atob(base64Data);
    const length = binaryString.length;
    const bytes = new Uint8Array(length);
    for (let i = 0; i < length; i++) {
        bytes[i] = binaryString.charCodeAt(i);
    }
    return bytes;
}

3. 将 Blob 或 Uint8Array 写入文件

在uni-app中,你可以使用uni.getFileSystemManager()来获取文件系统管理器,然后使用其方法进行文件写入操作。以下是将Blob对象写入文件的示例:

async function writeBlobToFile(blob, filePath) {
    const fs = uni.getFileSystemManager();
    const tempFilePath = `${wx.env.USER_DATA_PATH}/${filePath}`;
    
    try {
        await fs.writeFile({
            filePath: tempFilePath,
            data: blob,
            encoding: 'binary',
            success: () => {
                console.log('File written successfully');
            },
            fail: err => {
                console.error('Failed to write file:', err);
            }
        });
    } catch (err) {
        console.error('Error in file write:', err);
    }
}

对于Uint8Array,你可以直接将其传递给writeFile方法,但需要将encoding设置为'arraybuffer'

async function writeBytesToFile(bytes, filePath) {
    const fs = uni.getFileSystemManager();
    const tempFilePath = `${wx.env.USER_DATA_PATH}/${filePath}`;
    
    try {
        await fs.writeFile({
            filePath: tempFilePath,
            data: bytes.buffer, // Uint8Array.buffer gives ArrayBuffer
            encoding: 'arraybuffer',
            success: () => {
                console.log('File written successfully');
            },
            fail: err => {
                console.error('Failed to write file:', err);
            }
        });
    } catch (err) {
        console.error('Error in file write:', err);
    }
}

这些代码示例展示了如何在uni-app中处理Base64数据并将其写入文件。请确保在实际使用时处理可能的异常和错误情况。

回到顶部