如何使用Node.JS将部分流上传到Google云端硬盘

时间:2018-10-28 06:28:52

标签: node.js google-api google-drive-api google-api-nodejs-client

我想实现可以将文件的特定部分上传到Google云端硬盘的功能。我可以通过将原始读取流分成多个写入流,然后上载它们来做到这一点,但是这种技术是不可接受的,因为写入流将驻留在服务器上(我不想要)。

我试图通过在上载请求的正文中发送原始读取流来克服此问题,但是我找不到找到满足特定条件时停止上载的方法。我的上传功能如下:

/\badv\|/

有什么方法可以停止上传并在Google云端硬盘上完整保存上传的零件?我在流中尝试了多种操作,包括关闭,暂停,但似乎都没有停止上传的动作。我想补充的一点是,如果我已读取X字节的流并将其上传,则将上传正确的字节,即病房中X的字节。

1 个答案:

答案 0 :(得分:0)

基于此blog,您可以为收到的请求部件主体块添加处理程序。 像这样:

function write_chunk(request, fileDescriptor, chunk, isLast, closePromise) {
    // Pause receiving request data (until current chunk is written)
    request.pause();
    // Write chunk to file
    sys.debug("Writing chunk");
    posix.write(fileDescriptor, chunk).addCallback(function() {
        sys.debug("Wrote chunk");
        // Resume receiving request data
        request.resume();
        // Close file if completed
        if (isLast) {
            sys.debug("Closing file");
            posix.close(fileDescriptor).addCallback(function() {
                sys.debug("Closed file");

                // Emit file close promise
                closePromise.emitSuccess();
            });
        }
    });
}

function upload_file(req, res) {
     // Request body is binary
     req.setBodyEncoding("binary");


// Handle request as multipart
var stream = new multipart.Stream(req);

// Create promise that will be used to emit event on file close
var closePromise = new events.Promise();

// Add handler for a request part received
stream.addListener("part", function(part) {
    sys.debug("Received part, name = " + part.name + ", filename = " + part.filename);

    var openPromise = null;

    // Add handler for a request part body chunk received
    part.addListener("body", function(chunk) {
        // Calculate upload progress
        var progress = (stream.bytesReceived / stream.bytesTotal * 100).toFixed(2);
        var mb = (stream.bytesTotal / 1024 / 1024).toFixed(1);

        sys.debug("Uploading " + mb + "mb (" + progress + "%)");

        // Ask to open/create file (if not asked before)
        if (openPromise == null) {
            sys.debug("Opening file");
            openPromise = posix.open("./uploads/" + part.filename, process.O_CREAT | process.O_WRONLY, 0600);
        }

        // Add callback to execute after file is opened
        // If file is already open it is executed immediately
        openPromise.addCallback(function(fileDescriptor) {
            // Write chunk to file
            write_chunk(req, fileDescriptor, chunk, 
                (stream.bytesReceived == stream.bytesTotal), closePromise);
        });
    });
});

所有I / O调用都是异步的,因此不会立即执行write方法。因此,请使用addCallback的{​​{1}}方法来处理方法调用并用于通知。它表示要实现可靠的功能,需要events.Promiserequest.resume()以避免文件损坏。