NodeJS远程下载到本地FTP

时间:2016-06-09 14:53:21

标签: node.js asynchronous ftp

我试图将FTP服务器上的远程位置下载到我的本地目录。我一直在使用jsftp模块(https://github.com/sergi/jsftp),但我遇到了问题。

基本上我试图以递归方式下载整个远程位置,包括所有子文件夹等。我一直试图弄清楚自己,但到目前为止还没有运气。

到目前为止,我一直在尝试这个:

var worker = {
    ftp: null,
    init: function() {
        this.ftp = new JSFtp({
            host: "localhost",
            port: 21,
            user: "username",
            pass: "password"
        });
        this.ftp.auth("username", "password", function (result) {
            if (typeof result !== "undefined") {
                console.log("Something went wrong");
            }

            this.handleData();
        }.bind(this));
    },
    handleData: function () {
        recursive_get_files(this, "/");
    }
};
function recursive_get_files(worker, dir) {
    console.log("Getting directory: " + dir);
    worker.ftp.ls(dir, function (err, res) {
        res.forEach(function (file) {
            if (file.type === 1) {
                recursive_get_files(worker, dir + "/" + file.name);
            } else {
                worker.ftp.get(dir + "/" + file.name, "/downloads" + dir + "/" + file.name, function(err) {
                    if (err) {
                        console.log("Couldn't download file: " + file.name);
                        console.log(err);
                    }
                }.bind(file.name));
            }
        });
    });
}

我认为最大的问题是,所有这些get函数几乎都会立即被调用,并且由于客户端可能不允许调用这么多东西,它会破坏。

我已经看到一个名为ftpsync(https://www.npmjs.com/package/ftpsync)的模块做了一些远程同步,从本地到远程,但我需要这个。

有人能帮助我吗?我整天都被困在这/ =。

1 个答案:

答案 0 :(得分:0)

我能够通过以下方式与我的一位朋友解决这个问题:

function recursive_get_files(workerf, dir) {
    total_pending++;
    var worker = workerf;
    var done = function() {
        //probably callback here if needed
        console.log("finished downloading ftp");
        wrench.chmodSyncRecursive('downloads', 0777);
        worker.respond(JSON.stringify({type: "success", message: "Finished"}));
    };
    var func_download = function() {
        //Is the download queue empty?
        if(download_queue.length === 0)
        {
            total_running--;

            if(total_running === 0 && total_pending === 0)
            {
                done();
            }

            return;
        }

        //Get the next download in the queue
        var download = download_queue[0];
        download_queue.splice(0, 1);

        //Get a free FTP connection
        var curftp;
        for(curftp = 0; curftp < total; curftp++) {
            if (worker.ftp[curftp].used === false) {
                worker.ftp[curftp].used = true;
                break;
            }
        }

        //Get the file
        worker.ftp[curftp].ftp.get(download.dir + "/" + download.file.name, "downloads/" + worker.project + download.dir + "/" + download.file.name, function(file, err) {
            worker.ftp[curftp].used = false;
            if (err) 
            {
                console.log("Couldn't download file with FTP(" + curftp + "): " + file);
                console.log(err);
                setTimeout(func_download, 0);
            }
            else
            {
                console.log("Downloaded file with FTP(" + curftp + "): " + file);
                setTimeout(func_download, 0);
            }
        }.bind(null, download.file.name));
    };

    //Get a list of the current directory (Using the main connection)
    worker.mainftp.ls(dir, function (err, res) {
        res.forEach(function (file) {
            if (file.type === 1) 
            {
                mkdirp("downloads/" + worker.project + dir + "/" + file.name, function(err) {
                    if (err) console.log(err);
                    recursive_get_files(worker, dir + "/" + file.name);
                });
            } 
            else 
            {
                download_queue.push({file: file, dir: dir});

                if(total_running < total)
                {
                    total_running++;
                    setTimeout(func_download, 0);
                }
            }
        });
    });

    total_pending--;
    if(total_running === 0 && total_pending === 0 && download_queue.length === 0)
    {
        done();
    }
}

它使用wrench.js(用于递归chmod)和jsftp。感谢您阅读^^