1

我们正在利用 V Cloud API 与虚拟机交互(创建机器、执行操作、切换媒体等)。一个请求的功能是能够将媒体(特别是 ISO)上传到特定的目录。API 指南(第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 调用都返回.ISO 文件200 OK似乎很好,我们的内容范围标头永远不会超出既定文件大小,元数据似乎超出了我们的范围在编辑或测量方面进行控制。

希望有些人以前经历过这个问题,并可以提供一些洞察力来寻求解决方案

4

1 回答 1

2

事实证明,问题根本不在于 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)
         }

      }

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

于 2017-05-08T14:13:58.473 回答