ADN Open CIS
Сообщество программистов Autodesk в СНГ

03/04/2017

Возобновляемая загрузка файла при помощи Forge SDK на C#

Любой файл может быть загружен в Forge путем прямой загрузки в  Data Management API:

PUT buckets/:bucketKey/objects/:objectName

В то время, как это большой файл, загрузка напрямую небезопасна. Если подключение к Интернету капризничает, то загрузка будет прервана, что приведет к тому, что все предыдущие работы будут напрасными. Поэтому настоятельно рекомендуется использовать возобновляемую загрузку.

PUT buckets/:bucketKey/objects/:objectName/resumable

Базовая логика этого метода является разделение большого файла на части (chunks), а затем выгрузка частей одой за другой. Параметр этого HTTP-запроса (Session-Id) является строкой, которая уникально идентифицирует сессию, в которой файла загружается, с помощью которого Forge может знать, как объединить части вместе. 

Forge SDK   обеспечивает удобный способ для возобновляемой выгрузки. например, при помощи C # SDK. Тестовый пример  имеет демонстрацию только прямой выгрузки. Поэтому я добавил немного кода, основанного на примере, чтобы осуществить возобновляемую загрузку. 

Код - C#: [Выделить]
  1. private static dynamic resumableUploadFile()
  2.     {
  3.         Console.WriteLine("*****начать выгрузку большого файла");
  4.         string path = FILE_PATH;
  5.         if (!File.Exists(path))
  6.             path = @"..\..\..\" + FILE_PATH;
  7.  
  8.         // общий размер файла       
  9.         long fileSize = new System.IO.FileInfo(path).Length;
  10.         //размер части, допустим, 2M   
  11.         long chunkSize = 2 * 1024 * 1024 ;
  12.         // количество частей
  13.         long nbChunks = (long)Math.Round(0.5 + (double)fileSize / (double)chunkSize);
  14.         // записать глобальный ответ для следующей функции
  15.         ApiResponse<dynamic> finalRes = null ;
  16.         using (FileStream streamReader = new FileStream(path, FileMode.Open))
  17.         {
  18.             // уникальный идентификатор этой сессии
  19.             string sessionId = RandomString(12);
  20.             for (int i = 0; i < nbChunks; i++)
  21.             {
  22.                 // начальная двоичная позиция конкретного файла
  23.                 long start = i * chunkSize;
  24.                 // конечная двоичная позиция конкретного файла
  25.                 // если размер последней части больше, чем общий размер файла,
  26.                 // то конечная бинарная позиция будет конечной бинарной позицией файла
  27.                 long end = Math.Min(fileSize, (i + 1) * chunkSize) - 1;
  28.  
  29.                 // передать Forge информацию об этой части
  30.                 string range = "bytes " + start + "-" + end + "/" + fileSize;
  31.                 // длинна этой части
  32.                 long length = end - start + 1;
  33.  
  34.                 // прочитать файловый поток этой части
  35.                 byte[] buffer = new byte[length];
  36.                 MemoryStream memoryStream = new MemoryStream(buffer);
  37.  
  38.                 int nb = streamReader.Read(buffer, 0, (int)length);
  39.                 memoryStream.Write(buffer, 0, nb);
  40.                 memoryStream.Position = 0;
  41.  
  42.                 // выгрузить часть в Forge bucket
  43.                 ApiResponse<dynamic> response = objectsApi.UploadChunkWithHttpInfo(BUCKET_KEY,
  44.                         FILE_NAME, (int)length, range, sessionId, memoryStream,
  45.                         "application/octet-stream");
  46.  
  47.                 finalRes = response;
  48.  
  49.                 if (response.StatusCode == 202){
  50.                     Console.WriteLine("одна конкретная часть файла была выгружена");
  51.                     continue;
  52.                 }
  53.                 else if(response.StatusCode == 200){
  54.                     Console.WriteLine("последняя часть файла была выгружена");
  55.                 }
  56.                 else{
  57.                     // любая ошибка
  58.                     Console.WriteLine(response.StatusCode);
  59.                     break;
  60.  
  61.                 }
  62.             }
  63.                   
  64.         }
  65.                        
  66.         return (finalRes);
  67.     }

Источник: https://forge.autodesk.com/blog/c-resumable-upload-file-forge-sdk

Автор перевода: Дмитрий Емельянов

Обсуждение: http://adn-cis.org/forum/index.php?topic=

Опубликовано 03.04.2017