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

从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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:58:08