2017-04-19 28 views
0
public HttpWebResponse PushFileToWistia(byte[] contentFileByteArray, string fileName) 
    { 
     StringBuilder postDataBuilder = new StringBuilder(); 
     postDataBuilder.Append("I am appending all the wistia config and setting here"); 
     byte[] postData = null; 
     using (MemoryStream postDataStream = new MemoryStream()) 
     { 
      byte[] postDataBuffer = Encoding.UTF8.GetBytes(postDataBuilder.ToString()); 
      postDataStream.Write(postDataBuffer, 0, postDataBuffer.Length); 
      postDataStream.Write(contentFileByteArray, 0, contentFileByteArray.Length); 
      postDataBuffer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--"); 
      postDataStream.Write(postDataBuffer, 0, postDataBuffer.Length); 
      postData = postDataStream.ToArray(); 
     } 

     ServicePointManager.Expect100Continue = false; 
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(AppConfig.WistiaCustomCourseBucket); 
     request.Method = "POST"; 
     request.Expect = String.Empty; 
     request.Headers.Clear(); 
     request.ContentType = "multipart/form-data; boundary=" + boundary; 
     request.ContentLength = postData.Length; 

     Stream requestStream = request.GetRequestStream(); 
     requestStream.Write(postData, 0, postData.Length); //for file > 100mb this call throws and error --the requet was aborted. the request was canceled. 
     requestStream.Flush(); 
     requestStream.Close(); 

     HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
     return response; 
     } 

上述代碼適用於視頻文件mp4小於50mb。但是,當我嘗試上傳一個100MB的文件時,它會拋出異常(請求被中止)。我需要支持的文件大小高達1.5GB所以現在我不確定這種方法對於如此大的文件大小上傳是否正確。任何建議在正確的方向將是有益的...謝謝(我想上傳文件到Wistia服務器) 在這一行發生異常 - requestStream.Write(postData,0,postData.Length);寫請求流時請求被中止錯誤

我試圖改變的web.config的設置,但沒有奏效: 的httpRuntime targetFramework = 「4.5」 的maxRequestLength = 「2048576」 executionTimeout = 「12000」 requestLengthDiskThreshold = 「1024」

----- -async呼叫-------

 MemoryStream wistiaFileStream = null; 
     using (MemoryStream postDataStream = new MemoryStream()) 
     { 
      postDataStream.Write(contentFileByteArray, 0, contentFileByteArray.Length); 
      wistiaFileStream = postDataStream; 
      postDataStream.Flush(); 
      postDataStream.Close(); 
     } 

     Stream requestStream = await request.GetRequestStreamAsync(); 
     await requestStream.WriteAsync(wistiaMetadata, 0, wistiaMetadata.Length); 

using (wistiaFileStream) 
     { 
      byte[] wistiaFileBuffer = new byte[500*1024]; 
      int wistiaFileBytesRead = 0; 

      while (
       (wistiaFileBytesRead = 
        await wistiaFileStream.ReadAsync(wistiaFileBuffer, 0, wistiaFileBuffer.Length)) != 0) 
      { 
       await requestStream.WriteAsync(wistiaFileBuffer, 0, wistiaFileBytesRead); 
       await requestStream.FlushAsync(); 
      } 
      await requestStream.WriteAsync(requestBoundary, 0, requestBoundary.Length); 
     } 

回答

1

我建議移動到異步並直接從文件系統寫入文件,以避免在存儲器1.5GB的三重緩衝請求(下面警告是不測試)。

public async Task<HttpWebResponse> PushFileToWistiaAsync(string contentFilePath) 
{ 
    string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); 
    string contentBoundary = "\r\n--" + boundary + "\r\n"; 

    StringBuilder wistiaMetadataBuilder = new StringBuilder(); 
    wistiaMetadataBuilder.Append("--" + boundary + "\r\n"); 
    // Append all the wistia config and setting here 

    byte[] wistiaMetadata = Encoding.UTF8.GetBytes(wistiaMetadataBuilder.ToString()); 
    byte[] requestBoundary = Encoding.UTF8.GetBytes(contentBoundary); 

    ServicePointManager.Expect100Continue = false; 

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(AppConfig.WistiaCustomCourseBucket); 
    request.Method = "POST"; 
    request.Headers.Clear(); 
    request.Expect = String.Empty; 
    request.ContentType = "multipart/form-data; boundary=" + boundary; 

    Stream requestStream = await request.GetRequestStreamAsync(); 
    await requestStream.WriteAsync(wistiaMetadata, 0, wistiaMetadata.Length); 
    using (FileStream wistiaFileStream = new FileStream(contentFilePath, FileMode.Open, FileAccess.Read)) 
    { 
     byte[] wistiaFileBuffer = new byte[500 * 1024]; 
     int wistiaFileBytesRead = 0; 

     while ((wistiaFileBytesRead = await wistiaFileStream.ReadAsync(wistiaFileBuffer, 0, wistiaFileBuffer.Length)) != 0) 
     { 
      await requestStream.WriteAsync(wistiaFileBuffer, 0, wistiaFileBytesRead); 
      await requestStream.FlushAsync(); 
     } 
    } 
    await requestStream.WriteAsync(requestBoundary, 0, requestBoundary.Length); 

    return (HttpWebResponse)(await request.GetResponseAsync()); 
} 

你應該和緩衝區大小,你讀一次,並request.SendChunked實現合理的性能數據量播放。

這裏是另一種方法(不是異步那麼可能是最壞的可擴展性),這直接wirtes從緩衝區要求:

public HttpWebResponse PushFileToWistia(byte[] contentFileByteArray) 
{ 
    string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); 
    string contentBoundary = "\r\n--" + boundary + "\r\n"; 

    StringBuilder wistiaMetadataBuilder = new StringBuilder(); 
    wistiaMetadataBuilder.Append("--" + boundary + "\r\n"); 
    // Append all the wistia config and setting here 

    byte[] wistiaMetadata = Encoding.UTF8.GetBytes(wistiaMetadataBuilder.ToString()); 
    byte[] requestBoundary = Encoding.UTF8.GetBytes(contentBoundary); 

    ServicePointManager.Expect100Continue = false; 

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(AppConfig.WistiaCustomCourseBucket); 
    request.Method = "POST"; 
    request.Headers.Clear(); 
    request.Expect = String.Empty; 
    request.ContentType = "multipart/form-data; boundary=" + boundary; 
    request.ContentLength = wistiaMetadata.Length + contentFileByteArray.Length + requestBoundary.Length 

    // You can play with SendChunked and AllowWriteStreamBuffering to control the size of chunks you send and performance 
    //request.SendChunked = true; 
    //request.AllowWriteStreamBuffering = false; 

    int contentFileChunkSize = 500 * 1024; 
    int contentFileBytesRead = 0; 

    Stream requestStream = request.GetRequestStream(); 
    requestStream.Write(wistiaMetadata, 0, wistiaMetadata.Length); 
    while (contentFileBytesRead < contentFileByteArray.Length) 
    { 
     if ((contentFileBytesRead + contentFileChunkSize) > contentFileByteArray.Length) 
     { 
      contentFileChunkSize = contentFileByteArray.Length - contentFileBytesRead; 
     } 

     requestStream.Write(contentFileByteArray, contentFileBytesRead, contentFileChunkSize); 
     requestStream.Flush(); 

     contentFileBytesRead += contentFileChunkSize; 
    } 
    requestStream.Write(requestBoundary, 0, requestBoundary.Length); 
    requestStream.Close(); 

    // You might need to play with request.Timeout here 
    return (HttpWebResponse)request.GetResponse(); 
} 

此外,如果你的Web應用程序這樣做的,你要使用異步方法,你需要「異步/等待「(async控制器中的異步操作等)。

一般來說,我會勸阻這樣做,作爲Web應用程序中請求處理的一部分(從用戶角度觀察的總時間應該是上傳到您的應用程序,然後到Wistia的總和,這可能遠遠超過客戶端超時允許) 。在這種情況下,通常最好保存文件並安排一些其他「後臺任務」來完成上傳作業。

+0

我沒有從磁盤讀取文件我從HTML文件上傳中獲取文件。我不得不修改上面的解決方案,以適應我的代碼。它正確運行異步調用witohut任何錯誤。它將成功消息返回給客戶端Ux。但我沒有看到WISTIA服務器上的任何文件..它運行如此之快的1.5 GB文件,我不認爲它實際上發送文件內容WISTIA ..有沒有一種方法,我們可以阻止所有其他的執行,直到我們完成異步調用並獲得成功狀態...我在問題 – Scorpio

+0

@Scorpio中添加了編輯的代碼您的實現沒有拋出異常嗎?如果我正確閱讀,當您開始閱讀時,wistiaFileStream會關閉。如果你真的必須將文件保存爲字節數組(這是危險的,因爲在10個並行請求的情況下,最終可能會分配15 GB),我建議直接從該數組寫入請求。我會嘗試編輯我的答案以表明這一點。 – tpeczek

+0

@Scorpio爲不同的方法和一些一般建議添加了一個示例 – tpeczek

相關問題