2017-09-09 4 views
0

Nous écrivons une application pour transférer du contenu d'un compte OneDrive vers Azure Storage. Nous avons réussi à faire fonctionner cela, mais nous avons rencontré des problèmes de mémoire en travaillant avec de gros fichiers (> 1 Go) et Block Blobs. Nous avons décidé que les Append Blobs sont la meilleure façon d'aller de l'avant car cela résoudra les problèmes de mémoire.Téléchargement d'un fichier à partir de OneDrive vers Azure - problèmes avec le contenu du fichier

Nous utilisons un appel RPC pour SharePoint pour obtenir le flux de fichiers pour des fichiers volumineux, plus d'informations peuvent être trouvées ici: http://sharepointfieldnotes.blogspot.co.za/2009/09/downloading-content-from-sharepoint-let.html

En utilisant le code suivant fonctionne très bien lors de l'écriture du fichier de onedrive au niveau local stockage

using (var strOut = System.IO.File.Create("path")) 
using (var sr = wReq.GetResponse().GetResponseStream()) 
{ 

    byte[] buffer = new byte[16 * 1024]; 
    int read; 
    bool isHtmlRemoved = false; 
    while ((read = sr.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     if (!isHtmlRemoved) 
     { 
      string result = Encoding.UTF8.GetString(buffer); 
      int startPos = result.IndexOf("</html>"); 
      if (startPos > -1) 
      { 
       //get the length of the text, '</html>' as well 
       startPos += 8; 

       strOut.Write(buffer, startPos, read - startPos); 

       isHtmlRemoved = true; 
      } 
     } 
     else 
     { 
      strOut.Write(buffer, 0, read); 

     } 
    } 
} 

Cela crée le fichier avec la bonne taille, mais quand nous essayons d'écrire à un blob append dans Azure Storage, nous ne reçoivent pas le dossier complet et dans d'autres cas obtenir des fichiers plus gros.

using (var sr = wReq.GetResponse().GetResponseStream()) 
{ 

    byte[] buffer = new byte[16 * 1024]; 
    int read; 
    bool isHtmlRemoved = false; 
    while ((read = sr.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     if (!isHtmlRemoved) 
     { 
      string result = Encoding.UTF8.GetString(buffer); 
      int startPos = result.IndexOf("</html>"); 
      if (startPos > -1) 
      { 
       //get the length of the text, '</html>' as well 
       startPos += 8; 

       //strOut.Write(buffer, startPos, read - startPos); 
       appendBlob.UploadFromByteArray(buffer, startPos, read - startPos); 

       isHtmlRemoved = true; 
      } 
     } 
     else 
     { 
      //strOut.Write(buffer, 0, read); 
      appendBlob.AppendFromByteArray(buffer, 0, read); 

     } 
    } 
} 

Est-ce la bonne façon de le faire? Pourquoi obtiendrions-nous des tailles de fichier différentes?

Toutes les suggestions seront appréciées

Merci

Répondre

0

En réponse à "Pourquoi serions-nous obtenons des tailles de fichier?":

  1. De l'CloudAppendBlob.appendFromByteArray documentation « Cette API devrait être utilisé strictement dans un seul scénario d'auteur car l'API utilise en interne l'en-tête conditionnel d'adjonction-offset pour éviter les blocs en double qui ne fonctionnent pas dans un scénario à plusieurs auteurs . " Si vous utilisez en effet un seul graveur, vous devez définir explicitement la valeur de BlobRequestOptions.AbsorbConditionalErrorsOnRetry à true.

  2. Vous pouvez également vérifier si vous dépassez la limite de 50 000 blocs validés . Vos tailles de blocs sont relativement petites, c'est donc une possibilité avec des fichiers suffisamment volumineux (> 16KB * 50,000 = .82 Go).

En réponse à "Est-ce la bonne façon de le faire?":

  1. Si vous sentez que vous devez utiliser Append Blobs, essayez d'utiliser la méthode CloudAppendBlob.OpenWrite pour obtenir des fonctionnalités similaires à votre exemple de code pour le stockage local. Block Blobs semblent être plus adaptés à votre scénario. Pouvez-vous s'il vous plaît poster le code que vous utilisiez pour télécharger Block Blobs? Vous devriez être capable de télécharger vers Blob Block sans manquer de mémoire. Vous pouvez télécharger différents blocs en parallèle pour obtenir un débit plus rapide. L'utilisation d'Append Blobs pour ajouter (relativement) de petits blocs entraînera une dégradation des performances de lecture séquentielle, car les blocs append actuellement ne sont pas défragmentés.

Veuillez me faire savoir si l'une de ces solutions fonctionne pour vous!