简体   繁体   English

node.js在覆盖时无法提供图像

[英]node.js unable to serve image when it is being overwritten

I have a node.js app that periodically poll images and store them onto filesystem. 我有一个node.js应用程序,该应用程序定期轮询图像并将其存储到文件系统中。

The problem is, when node.js is overwriting the images, whoever that visits the website at that moment will see blank images everywhere (because the images is being overwritten at that moment). 问题是,当node.js覆盖图像时,那时访问该网站的任何人到处都会看到空白图像(因为此时图像已被覆盖)。

This only happens for that few seconds whenever it is time to poll the images, but it is annoying. 每当需要轮询图像时,这种情况只会持续几秒钟,但这很烦人。 Is there anyway to be able to still serve the image while we are overwriting it? 无论如何,在我们覆盖图像时是否仍然可以提供图像?

Code to save/overwrite image: 保存/覆盖图像的代码:

// This method saves a remote path into a file name.
// It will first check if the path has something to download
function saveRemoteImage(path, fileName)
{
    isImagePathAvailable(path, function(isAvailable)
    {
        if(isAvailable)
        {
            console.log("image path %s is valid. download now...", path);   
            console.log("Downloading image file from %s -> %s", path, fileName);
            var ws = fs.createWriteStream(fileName);
            ws.on('error', function(err) { console.log("ERROR DOWNLOADIN IMAGE FILE: " + err); });
            request(path).pipe(ws);         
        }
        else
        {
            console.log("image path %s is invalid. do not download.");
        }
    });
}

Code to serve image: 投放图片的代码:

fs.exists(filePath, function(exists) 
    {
        if (exists) 
        {
            // serve file
            var stat = fs.statSync(filePath);
            res.writeHead(200, {
                'Content-Type': 'image/png',
                'Content-Length': stat.size
            });

            var readStream = fs.createReadStream(filePath);
            readStream.pipe(res);
            return;
        } 

I'd suggest writing the new version of the image to a temporary file: 我建议将图像的新版本写入一个临时文件:

var ws = fs.createWriteStream(fileName + '.tmp');
var temp = request(path).pipe(ws);         

and renaming it when the file is entirely downloaded: 并在文件完全下载后重命名

temp.on('finish', function() {
    fs.rename(fileName + '.tmp', fileName);
});

We use the 'finish' event , which is fired when all the data has been written to the underlying system, ie. 我们使用'finish'事件 ,当所有数据都已写入底层系统时即触发。 the filesystem. 文件系统。

May be it is better to 也许更好

  • serve the old version of file while downloading; 下载时提供旧版本的文件;
  • download new file to temporary file (say _fileName , for example); 将新文件下载到临时文件(例如_fileName );
  • rename file after downloading thus rewriting original file; 下载后重命名文件,从而重写原始文件;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM