You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Node.js和Redis实现图片缓存时的文件损坏问题

Redis缓存图片后无法显示且文件大小翻倍的问题与修复

我尝试使用Redis缓存图片文件,但从Redis读取后图片可下载却无法显示,且读取后的文件大小约为原文件的两倍,原实现代码如下:

import express from 'express';
import { Redis } from 'ioredis';
import fs from 'fs';
import { Readable } from 'node:stream'

const redis = new Redis();
const app = express();
const key = 'theKey';

app.get('', async (req, res) => {
    res.set({
        'Content-Type': 'image/png',
        'Content-Disposition': `attachment; filename="image.png"`,
    });

    const file = fs.createReadStream('./image.png');

    const cached = await redis.getBuffer(key);

    if (cached) {
        const file = Readable.from(cached);
        file.pipe(res);
    } else {
        await cacher(file);
        file.pipe(res);
    }
})

app.listen(3000, () => console.log('Server is running on 3000'))


async function cacher(readable) {
    const buffer = [];
    readable.on('data', (chunk) => {
        buffer.push(chunk);
    })
    readable.on('end', () => {
        const mergedBuffers = buffer.join();
        const buf = Buffer.from(mergedBuffers);
        redis.setBuffer(key, buf);
        redis.expire(key, 5)
    })
}

问题原因

问题出在cacher函数中的buffer.join()调用:当对Buffer数组使用join()方法时,会将每个Buffer转换为字符串(默认以逗号分隔),再通过Buffer.from()转回二进制格式。这个过程会破坏图片的原始二进制数据,导致文件损坏无法显示,同时额外的分隔符和字符串转换会使文件体积翻倍。

修复方案

使用Buffer.concat()替代join()来合并Buffer数组,Buffer.concat()会直接拼接二进制数据,完整保留文件的原始内容。修复后的cacher函数如下:

async function cacher(readable) {
    const bufferArr = []
    readable.on('data', (chunk) => {
        bufferArr.push(chunk)
    })
    readable.on('end', () => {
        redis.setBuffer(key, Buffer.concat(bufferArr));
        redis.expire(key, 5)
    })
}

内容的提问来源于stack exchange,提问作者mobin kazemi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 12:17:16