将文件从OneDrive上传到Azure - 文件内容问题

时间:2017-09-09 09:20:08

标签: c# azure sharepoint azure-storage onedrive

我们编写了一个应用程序,用于将内容从OneDrive帐户移动到Azure存储中。我们设法使其工作,但遇到了处理大文件(> 1GB)和Block Blobs的内存问题。我们已经确定Append Blobs是未来的最佳方式,因为这将解决内存问题。

我们正在使用对SharePoint的RPC调用来获取大文件的文件流,可在此处找到更多信息:  http://sharepointfieldnotes.blogspot.co.za/2009/09/downloading-content-from-sharepoint-let.html

将文件从OneDrive写入本地存储

时,使用以下代码正常工作
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);

        }
    }
}

这会创建具有正确大小的文件,但是当我们尝试将其写入Azure存储中的附加blob时,我们无法获取完整文件,并且在其他情况下会获得更大的文件。

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);

        }
    }
}

这是正确的做法吗?为什么我们会得到不同的文件大小?

任何建议都将受到赞赏

由于

1 个答案:

答案 0 :(得分:0)

回应“为什么我们会获得不同的文件大小?”:

  1. 来自CloudAppendBlob.appendFromByteArray documentation “此API应严格用于单个编写器方案 因为API内部使用append-offset条件头 避免在多个编写器中不起作用的重复块 场景。“如果你确实在使用一个作家,你需要 明确设置值 BlobRequestOptions.AbsorbConditionalErrorsOnRetrytrue

  2. 您还可以检查是否超过了50,000个已提交的块 限制。你的块大小相对较小,所以这是一个 文件足够大的可能性(> 16KB * 50,000 = .82 GB)。

  3. 回应“这是正确的做法吗?”

    1. 如果您认为需要使用附加Blob,请尝试使用CloudAppendBlob.OpenWrite方法实现更类似于本地存储的代码示例的功能。

    2. 阻止Blob看起来可能更适合您的场景。您能否发布用于上传Block Blob的代码?您应该可以上传到Block Blobs而不会耗尽内存。您可以并行上传不同的块以实现更快的吞吐量。使用Append Blob追加(相对)小块将导致顺序读取性能下降,因为当前附加块未进行碎片整理。

    3. 如果这些解决方案适合您,请告诉我们!