首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用gridfs-stream进行替换?

如何使用gridfs-stream进行替换?
EN

Stack Overflow用户
提问于 2013-06-17 11:51:43
回答 1查看 813关注 0票数 0

我正在使用以下代码进行文件更新:

代码语言:javascript
复制
app.post("/UploadFile", function(request, response)
{
    var file = request.files.UploadedFile;

    var name = request.param("Name");
    var componentId = request.param("ComponentId");

    console.log("Uploading: " + name);

    var parameters =
    {
        filename: name,
        metadata:
        {
            Type: "Screenshot",
            ComponentId: componentId
        }
    };

    grid.files.findOne( { "metadata.ComponentId" : componentId }, function(error, existing)
    {
        console.log("done finding");
        if (error)
        {
            common.HandleError(error);
        }
        else
        {
            if (existing)
            {
                console.log("Exists: " + existing._id);
                grid.remove({ _id: existing._id }, function(removeError)
                {
                    if (removeError)
                    {
                        common.HandleError(removeError, response);
                    }
                    else
                    {
                        SaveFile(file, parameters, response);
                    }
                });
            }
            else
            {
                console.log("new");
                SaveFile(file, parameters, response);
            }
        }
    });
});

function SaveFile(file, parameters, response)
{
    console.log("Saving");
    var stream = grid.createWriteStream(parameters);

    fs.createReadStream(file.path).pipe(stream);
}

基本上,我检查的是一个ID存储在元数据中的文件。如果它存在,我会在保存之前将其删除,如果不存在,则只进行保存。它似乎只能偶尔起作用。我有时会看到两种错误的行为:

该文件将被删除,但不会重新创建。

这个文件看起来已经更新了,但是直到我再次调用我的代码,它才会真正被替换。所以基本上我需要上传两个文件来注册替换。

这是非常粗略的,我真的不能确定它是否会工作的模式。

所以我假设我做错了什么。使用gridfs-stream替换文件的正确方法是什么?

EN

回答 1

Stack Overflow用户

发布于 2013-12-09 09:02:24

仅从您提供的代码中很难确定(即,您没有展示app.postresponse最终是如何处理的),但我看到了几个需要检查的危险信号:

在您的文件和gridFS存储之间设置pipe后,上面的SaveFile函数将立即返回。也就是说,如果您正在移动大文件,和/或如果您的MongoDB存储是通过相对较慢的链接(例如互联网)进行的,那么在将文件完全复制到MongoDB实例之前,上面提供的代码的调用者很可能会获得控制权。

在这些情况下,调用者很可能会在pipe仍在运行时立即进行检查,因此在gridFS存储包含文件的正确副本之前进行检查。

另一个问题是,您没有对您创建的流可能生成的事件进行任何错误检查或处理。

修复可能涉及在管道上创建适当的事件处理程序,如下所示:

代码语言:javascript
复制
function SaveFile(file, parameters, response)
{
    console.log("Saving");
    var stream = grid.createWriteStream(parameters);

    pipe = fs.createReadStream(file.path).pipe(stream);

    pipe.on('error', function (err) {
         console.error('The write of " + file.path + " to gridFS FAILED: ' + err);
         // Handle the response to the caller, notifying of the failure 
    });

    pipe.on('finish', function () {
         console.log('The write of " + file.path + " to gridFS is complete.');
         // Handle the response to the caller, notifying of success 
    });
}

在传输完成之前,不会调用处理'finish'事件的函数,因此这是响应app.post请求的适当位置。如果没有其他问题,您应该从错误事件中获得有用的信息,以帮助进一步诊断此问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17140172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档