【问题标题】:reassemble binary after flow.js upload on node/express server在 node/express 服务器上上传 flow.js 后重新组装二进制文件
【发布时间】:2014-05-03 19:48:37
【问题描述】:

我不知道如何将 flow.js 库与节点后端一起使用,并且我的代码基于 flow.js github 上的示例。

我正在获取 blob 文件,但在上传完成后我没有构建二进制文件。最终获取未触发或我的路线错误:

  app.get('/download/:identifier', function(req, res){
    console.log('we writin')
    flow.write(req.params.identifier, res);
  });

任何有这方面经验的人都可能获得一百万个 stackoverflow pts,因为这似乎是使用 node.js 和 flow.js 时的常见问题,还有另外两个未回答的问题:

Flowjs file upload - AngularJS and Node Reassembling file chunks produced in a multi-part upload

【问题讨论】:

    标签: node.js file-upload asyncfileupload flow-js


    【解决方案1】:

    我找到了一种可行的方法,但可能不是理想的方法。

    如果statusdonecurrentTestChunk > numberOfChunks,我在flow.post 中调用flow.write。我会进行大于检查,因为有时flow.post 会多次发送status done,如here 所述。

    编辑:我添加了一种在创建文件后清理块的方法。

    flow.post(req, function(status, filename, original_filename, identifier, currentTestChunk, numberOfChunks) {
            console.log('POST', status, original_filename, identifier);
            res.send(200);
            if (status === 'done' && currentTestChunk > numberOfChunks) {
                var stream = fs.createWriteStream('./tmp/' + filename);
                //EDIT: I removed options {end: true} because it isn't needed
                //and added {onDone: flow.clean} to remove the chunks after writing
                //the file.
                flow.write(identifier, stream, { onDone: flow.clean });            
            }            
        })
    

    我不得不修改flow.post 的回调来发送currentTestChunknumberOfChunks

    文件:flow-node.js

    $.post = function(req, callback){
    
    //There's some codez here that we can overlook...
    
      fs.rename(files[$.fileParameterName].path, chunkFilename, function(){
    
        // Do we have all the chunks?
        var currentTestChunk = 1;
        var numberOfChunks = Math.max(Math.floor(totalSize/(chunkSize*1.0)), 1);
        var testChunkExists = function(){
              fs.exists(getChunkFilename(currentTestChunk, identifier), function(exists){
                if(exists){
                  currentTestChunk++;
                  if(currentTestChunk>numberOfChunks) {
    
                    //Add currentTestChunk and numberOfChunks to the callback
    
                    callback('done', filename, original_filename, identifier, currentTestChunk, numberOfChunks);
                  } else {
                    // Recursion
                    testChunkExists();
                  }
                } else {
    
                  //Add currentTestChunk and numberOfChunks to the callback
    
                  callback('partly_done', filename, original_filename, identifier, currentTestChunk, numberOfChunks);
                }
              });
            }
        testChunkExists();
      });
    } else {
          callback(validation, filename, original_filename, identifier);
    }
    

    }

    如果你想删除块,在 flow.write 中调用 flow.clean 和 onDone。

      $.write = function(identifier, writableStream, options) {
          options = options || {};
          options.end = (typeof options['end'] == 'undefined' ? true : options['end']);
    
          // Iterate over each chunk
          var pipeChunk = function(number) {
    
              var chunkFilename = getChunkFilename(number, identifier);
              fs.exists(chunkFilename, function(exists) {
    
                  if (exists) {
                      // If the chunk with the current number exists,
                      // then create a ReadStream from the file
                      // and pipe it to the specified writableStream.
                      var sourceStream = fs.createReadStream(chunkFilename);
                      sourceStream.pipe(writableStream, {
                          end: false
                      });
                      sourceStream.on('end', function() {
                          // When the chunk is fully streamed,
                          // jump to the next one
                          pipeChunk(number + 1);
                      });
                  } else {
                      // When all the chunks have been piped, end the stream
                      if (options.end) {
                              writableStream.end();
                          }
    
                      //Options.onDone contains flow.clean so here I'm deleting all the chunked files.
    
                      if (options.onDone) {
                          options.onDone(identifier);
                      }
                  }
              });
          }
          pipeChunk(1);
      }
    

    【讨论】:

    • 太棒了!你有机会向 flow.Js github repo 提交 PR 吗?这是一个链接:github.com/flowjs/flow.js/issues/17#issuecomment-49737531
    • 嘿@flashpunk,有机会我会调查的。
    • 我看不出如何在第一次检查后立即在回调中重复检查“if(currentTestChunk>numberOfChunks)”可以帮助解决多次触发完成状态的问题。
    • 此处记录了重复的完成状态问题:github.com/flowjs/flow.js/issues/16。它被错误地标记为已关闭,但以下评论看起来更有可能修复:github.com/flowjs/flow.js/issues/16#issuecomment-50160924
    • @ChrisFoster 这是一种解决方法,而不是解决问题的方法。当我观察到状态done 被多次发送时,currentTestChunk 还没有大于 numberOfChunks。所以检查只是确保 flow.write 在所有块都被写入后执行。我尽量避免同步代码,这是您发布的链接中的解决方案。
    【解决方案2】:

    好的,所以我一直在研究这个并想出了这个,希望它能让有人开始......

    exports.post = function (req, res, next) {
    
        flow.post(req, function(status, filename, original_filename, identifier) {
    
            console.log('status: '+ status, filename, original_filename, identifier);
    
            if(status==='done'){
    
                var s = fs.createWriteStream('./uploads/' + filename);
                s.on('finish', function() {
    
                    res.send(200, {
                        // NOTE: Uncomment this funciton to enable cross-domain request.
                        //'Access-Control-Allow-Origin': '*'
                    });
    
                });
    
                flow.write(identifier, s, {end: true});
            }
    
        });
    
    };
    

    【讨论】:

      【解决方案3】:

      我已经发出了一个拉取请求,它将重新组装逻辑添加到 Flow.js 的 Node 示例中。请参阅 https://github.com/flowjs/flow.js/pull/71https://github.com/flowjs/flow.js/issues/17

      【讨论】:

        猜你喜欢
        • 2021-06-24
        • 1970-01-01
        • 2014-06-23
        • 1970-01-01
        • 1970-01-01
        • 2014-11-19
        • 1970-01-01
        • 2021-08-15
        相关资源
        最近更新 更多