从MongoDB获取GridFS文件时提示‘file not found’问题求助
解决GridFS读取文件提示"File Not Found"的问题
我完全懂你现在的困扰——明明数据库里清清楚楚存着对应文件名的文件,但是用gfs.exist()就是查不到,返回文件不存在。我帮你分析下可能的问题点,以及对应的解决办法:
问题排查与解决方案
1. 替换不可靠的gfs.exist()方法
gridfs-stream的exist()方法在某些版本中存在兼容性问题,不如直接查询GridFS的文件集合来得可靠。建议改用gfs.files.findOne()来检查文件是否存在。
2. 调整代码结构,确保GridFS初始化完成再处理请求
你的路由定义放在了connection.once('open')回调内部,可能导致路由注册不及时,或者请求到来时gfs还没完成初始化。
修改后的完整代码
let mongoose = require('mongoose'); let gridfs = require('gridfs-stream'); const express = require('express'); const router = express.Router(); // 全局声明gfs,确保路由能访问到 let gfs; mongoose.connect('mongodb://foo123.mlab.com:123456/db_name', { auth: { user: 'username', password: 'password' } }) .then(() => console.log('connection successful')) .catch((err) => console.error(err)); mongoose.Promise = global.Promise; gridfs.mongo = mongoose.mongo; const connection = mongoose.connection; connection.on('error', console.error.bind(console, 'connection error:')); connection.once('open', () => { // 初始化GridFS gfs = gridfs(connection.db); console.log('GridFS initialized successfully'); // 可选:打印所有文件,确认数据库中存在目标文件 gfs.files.find().toArray((err, files) => { if (err) console.error(err); else console.log('All files in GridFS:', files); }); }); // 把路由定义移到外部,确保请求能正确触发 router.post('/', (req, res) => { // 先检查GridFS是否初始化完成 if (!gfs) { return res.status(500).send('GridFS is not ready yet'); } const targetFilename = '6866866-Tue-May-29-2018.jpg'; // 直接查询文件集合 gfs.files.findOne({ filename: targetFilename }, (err, file) => { if (err) { console.error('Error querying file:', err); return res.status(500).send('Failed to check file existence'); } if (!file) { return res.send('File Not Found'); } // 创建读取流并返回给客户端 const readstream = gfs.createReadStream({ filename: file.filename }); // 处理流的错误 readstream.on('error', (streamErr) => { console.error('Error reading file stream:', streamErr); res.status(500).send('Failed to read file'); }); readstream.pipe(res); }); }); module.exports = router;
额外检查点
- 确认Bucket名称:如果上传文件时指定了自定义的Bucket名称(比如
bucketName: 'myFiles'),初始化gfs时也要对应加上:gfs = gridfs(connection.db, { bucketName: 'myFiles' }),否则会默认查询fs.files集合,而你的文件可能存在其他集合中。 - 数据库权限:确保你用于连接的MLab用户拥有读取
fs.files和fs.chunks集合的权限,避免因权限不足导致查询失败。 - 文件名一致性:虽然你看起来文件名完全一致,但可以复制数据库中的文件名直接粘贴到代码中,避免手动输入时的隐藏字符(比如空格、大小写差异)。
内容的提问来源于stack exchange,提问作者obiwankenoobi
相关产品推荐
相关产品推荐

