【问题标题】:Upload of Media via VMware API results in larger transferred size than file size通过 VMware API 上传媒体会导致传输大小大于文件大小
【发布时间】:2017-05-01 19:05:32
【问题描述】:

我们正在利用 V Cloud API 与虚拟机交互(创建机器、执行操作、切换媒体等)。一个请求的功能是能够将媒体(特别是 ISO)上传到特定的目录。 API guide (pg 67) 相当简单,我们对上传开始时提供的 URL 的多部分请求顺利进行。

注意:我们必须在开始上传之前声明文件大小

在上传过程中唯一看起来有问题的是“传输的大小”最终大于过程结束时的“文件大小”。这有点奇怪,因为我们的内容范围永远不会超过预期的文件大小(我们假设元数据被包含在我们没有发言权的情况下)。一旦此传输大小超过文件大小,文件上传状态将更改为“错误”但仍返回200 OK

    {
  "name": "J Small 4",
  "description": "",
  "files": [{
    "name": "file",
    "totalSize": 50696192,
    "status": "Error",
    "link": "https://cloud01.cs2cloud.com/transfer/27b8f93c-8319-419e-9e8c-15622097670b/file",
    "transferredSize": 54293177
  }],
  "id": "urn:vcloud:media:1cec68ef-f22e-4ec7-ae5d-dfbc4f7137d9",
  "catalogId": "urn:vcloud:catalogitem:19dbfdd8-ea70-4355-abc7-96e34dccb869"
}

不确定从哪里开始调试,因为所有 API 调用都返回 200 OK.ISO file 似乎很好,我们的内容范围标头永远不会超出既定文件大小,元数据在编辑或测量方面似乎超出了我们的控制范围。

希望有人曾经经历过这个问题,并且可以提供一些洞察力来帮助解决问题

【问题讨论】:

    标签: file-upload vmware multipartform-data vcloud-director-rest-api


    【解决方案1】:

    事实证明,问题根本不在于 vmware,而在于我们如何将媒体文件分块。我们最初使用FileReader() 将文件分块并将其发送到VMware API。

    理论上,我们选择了块大小,然后可以生成和设置内容范围,但实际上我们选择了内容范围,但内容长度与块大小不同。我们仍然不完全确定它发生的原因(可能添加了额外的元数据),但我们找到了解决方案。

    修复:我们完全消除了 FileReader(),只是将文件切片直接放入一个 blob 中(您可以在下面看到)

    $scope.parseMediaFile = function(url, file, catalogId) {
             $scope.uploadingMediaFile = true;
    
             var fileSize = file.size;
             var chunkSize = 1024 * 1024 * 5; // bytes
             var offset = 0;
             var self = this; // we need a reference to the current object
             var chunkReaderBlock = null;
             var chunkNum = 0;
    
             if (fileSize < chunkSize) {
                chunkSize = fileSize;
             }
    
             chunkReaderBlock = function(_offset, length, _file) {
                var blob = _file.slice(_offset, length + _offset);
                var beginRange = _offset;
                var endRange = _offset + length;
    
                if(endRange > _file.size) {
                  endRange = _file.size
                }
    
                var contentRange = beginRange + "-" + endRange;
    
                vdcServices.uploadMediaFile(url, blob, fileSize, contentRange).then(
                  function(resp) {
                    vdcServices.getUploadStatus($scope.company, catalogId).then(function(resp) {
                      var uploaded = resp.data.files[0].transferredSize;
                      $scope.mediaPercentLoaded = $scope.trunc((uploaded / fileSize) * 100);
    
                      if (endRange == _file.size) {
                        $scope.closeModal();
                        return;
                      }
    
                      chunkReaderBlock(_offset+length, chunkSize, file);
                    }, function(err) {
                      $scope.errorMsg = err;
                      chunkReaderBlock(_offset-length, chunkSize, file);
                    })
                  },
                  function(err) {
                    $scope.errorMsg = err;
                  }
                )
             }
    
             // Starts the read with the first block
             if (offset < fileSize) {
                chunkReaderBlock(offset, chunkSize, file)
             }
    
          }
    

    这样做使我们能够实际上控制内容长度,并且由于我们可以确定传输的字节数何时等于文件大小,因此我们可以完成该过程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-27
      • 1970-01-01
      • 2014-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      相关资源
      最近更新 更多