node.js - 等待文件完成复制后再对其进行操作?

标签 node.js

我有一个简单的 node.js 应用程序,用于监视新 PDF 文件的目录。当它看到它们出现时,它会将它们通过 FTP 传输出去并将它们移动到另一个目录。

我遇到的问题是,如果文件恰好有点大(例如 10MB),我的应用程序会在文件完成复制到目录之前开始处理该文件。

复制是通过网络进行的,因此速度也会稍微慢一些。我需要一种方法来告诉我的应用程序等到文件复制完成后再处理它。

最好的方法是什么?我已经尝试过“增长文件”模块,但它似乎不起作用,而且看起来开发人员已经放弃了它。

预先感谢您的帮助。

最佳答案

我遇到了几乎同样的问题,我需要在播放文件之前下载文件。我最终编写了这段代码,您可以轻松地为您的操作重写该代码。

编辑:事实上,您几乎可以按原样使用代码,只需小心下载的回调即可。

它利用回调来逐个下载每个文件(我有带宽问题),但我有一个以前的版本,它开始所有下载,然后在回调之前等待所有文件都在磁盘上。

如果您想按原样使用它,您需要有一个名为 DOWNLOAD_DIR 的全局变量,其中包含下载目录的完整路径。

您还需要 http,但我认为您已经拥有它了。

var http = require('http');

/*download
IN_: file_url
        string
        url of the file to download
     callback
COM: Download the specified file to DOWNLOAD_DIR/name_of_the_file, and callback the full path to the file
     callback null on error.
*/
function download(file_url, callback) {
    var options = {
        host: url.parse(file_url).host,
        port: 80,
        path: url.parse(file_url).pathname
    },
        file_name = url.parse(file_url).pathname.split('/').pop(),
    //Creating the file
        file = fs.createWriteStream(DOWNLOAD_DIR + file_name, {flags: 'w', encoding: 'binary'}),
    console.log('Downloading file from ' + file_url);
    console.log(LOG, '\tto ' + file_name);
    http.get(options, function (res) {
        res.pipe(file, {end: 'false'});
        //When the file is complete
        res.on('end', function () {
            //Closing the file
            file.end();
            console.log(LOG, '\t\tDownloaded '+ file_name);
            callback(DOWNLOAD_DIR + file_name);
        });
    });

    process.on('uncaughtException', function(err) {
        console.log('Can t download ' + file_url + '\t(' + err + ')');
        callback(null);
    });

}

/*download_all
IN_: list
        array of string
        Names of the files to download
     callback
COM: Download all the file one after another
*/
function download_all(list, callback) {
    var i = 0, 
        fe;

    function follow() {
        //If there is download to do
        if (i < list.length) {
            //Checking if the file already exist
            fe = fs.existsSync(DOWNLOAD_DIR + list[i].substr(list[i].lastIndexOf('/')));
            console.log('Checking ' + list[i]);
            if (!fe) {
                console.log('\tDo not exist');
                //If it doesn t, downloading it
                download(list[i], function () {
                    i = i + 1;
                    //And go to the next file
                    follow();
                });
            } else {
                //If it does, go to the next file
                console.log('\tExist');
                i = i + 1;
                follow();
            }
        } else {
            //When all files are downloaded
            console.log('end');
            callback();
        }
    }
    follow();
}

请注意,在生产代码中,您应该将 fs.existSync(在下载中)替换为 fs.exist + 回调

编辑:这里是一次性下载的代码。请注意,这是我编辑过的旧代码。

请注意,这段代码很旧,我没有对其进行多次测试,并且也使用了 fs.existSync(这对于生产代码来说又是不利的)。

最后一点,如果下载失败,下载的回调中会有null参数,需要你自己检查一下。

/*download_all
IN_: list
        array of string
        Names of the files to download
     callback
COM: Download all-at-once
*/
function download_all(list, callback){
    var i=0, dltd, dlcp=0;
    dltd=list.length;

    function afterDownload(){
        dlcp=dlcp+1;
        console.log("Telechargement fini:"+dlcp);
        if(dlcp===dltd){
            callback();
        }
    }

    while(i<list.length)
    {
        if(!fs.existsSync(DOWNLOAD_DIR + list[i].substr(list[i].lastIndexOf('/'))))
        {
            //If the file do not exist
            download(list[i], afterDownload);
        } else {
            afterDownload();
        }
        i=i+1;
    }
}

示例:

var http = require('http'),
    DOWNLOAD_DIR = '/home/user/download/',
    list = ['http://somewebsite.com/video.mp4', 'http://somewebsite.com/video2.mp4', 'http://othersite.com/image.png'];

download_all(list, function (){
    //Do stuff
});

关于node.js - 等待文件完成复制后再对其进行操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20999235/

相关文章:

node.js - Nginx - 离开安全页面时将 HTTPS 重定向回 HTTP

Node.js - 如何为不同的路由设置单独的身份验证?

node.js - 为什么 babel-node-debug 无法识别 import 命令?

json - 如何在 Express 应用程序中使用 JSON POST 数据

javascript - 将鼠标悬停在文本上时创建叠加层

node.js - Nodejs 中的处理程序响应

javascript - 初学者 - 使用以下 While 循环时出现 "NaN"错误

javascript - 在 Angular 8 中导入 interactjs 1.7.2 不起作用

node.js - 如何从 socket.io 中访问 req.session 变量?

javascript - 使用 Jade Html 预处理器分别在每个 div 内包含一个 img 标签的多个 Div