使用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
相关产品推荐
相关产品推荐

