2016-05-12 61 views
1

我們正在閱讀文件的字節數組,並將其轉換成字符串的base64如下如何通過chunck字節數組將chunck轉換爲base64字符串?

public static string ZipToBase64() 
      { 
       FileUpload fileCONTENT = FindControl("FileUploadControl") as FileUpload; 

       byte[] byteArr = fileCONTENT.FileBytes; 

       return Convert.ToBase64String(byteArr); 

      } 

    string attachmentBytes = ZipToBase64(); 
    string json1 = "{ \"fileName\": \"Ch01.pdf\", \"data\": " + "\"" + attachmentBytes + "\"}"; 

當我們嘗試將大型文件轉換高達1 GB爲base64,字符串,則拋出內存異常。我們將這個json發送給restful wcf服務。以下是我在RESTful WCF服務中的方法。

[OperationContract] 
     [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] 
     public void UploadFile1(Stream input) 
     { 

      string UserName = HttpContext.Current.Request.Headers["UserName"]; 
      string Password = Sql.ToString(HttpContext.Current.Request.Headers["Password"]); 
      string sDevideID = Sql.ToString(HttpContext.Current.Request.Headers["DeviceID"]); 
      string Version = string.Empty; 
      if (validateUser(UserName, Password, Version, sDevideID) == Guid.Empty) 
      { 
       SplendidError.SystemWarning(new StackTrace(true).GetFrame(0), "Invalid username or password for " + UserName); 
       throw (new Exception("Invalid username or password for " + UserName)); 
      } 


      string sRequest = String.Empty; 
      using (StreamReader stmRequest = new StreamReader(input, System.Text.Encoding.UTF8)) 
      { 
       sRequest = stmRequest.ReadToEnd(); 
      } 
      // http://weblogs.asp.net/hajan/archive/2010/07/23/javascriptserializer-dictionary-to-json-serialization-and-deserialization.aspx 

      JavaScriptSerializer json = new JavaScriptSerializer(); 
      // 12/12/2014 Paul. No reason to limit the Json result. 
      json.MaxJsonLength = int.MaxValue; 

      Dictionary<string, string> dict = json.Deserialize<Dictionary<string, string>>(sRequest); 
      string base64String = dict["data"]; 
      string fileName = dict["fileName"]; 


      byte[] fileBytes = Convert.FromBase64String(base64String); 
      Stream stream = new MemoryStream(fileBytes); 

      //FileStream fs1 = stream as FileStream; 

      string networkPath = WebConfigurationManager.AppSettings["NetWorkPath"]; 
      File.WriteAllBytes(networkPath + "/" + fileName, fileBytes); // Requires System.IO 
     } 

請轉換大字節數組轉換爲字符串的base64

+0

發送1GB base64編碼字符串作爲json不是一個好主意,你不覺得嗎? – Evk

+0

@Evk感謝您的評論。我們正在使用android移動應用程序和Web應用程序來上傳文件。我們正在文件系統上的遠程服務器上傳文件。這就是爲什麼我寫了RESTFul wcf服務上傳文件 –

+0

但我的意思是 - 如果你的文件很大(比10MB多) - 你不應該在json中將它們序列化。你必須以流式傳遞的方式在請求正文中傳遞它們。對於RESTful wcf服務也是如此。我本來可以展示如何通過塊將byte []塊轉換爲base64,但這不會幫助你。 – Evk

回答

2

使用流輸入的事實在WCF服務並不真正意味着你傳遞流的方式提供任何解決方案。事實上在你的情況下,你不這樣做,因爲:

  1. 你在內存中的客戶端緩衝整個文件來建立json字符串。
  2. 您通過stmRequest.ReadToEnd()將整個文件緩衝在內存中的服務器上。

所以不會發生流式傳輸。首先你應該認識到這裏不需要json - 你只需要在你的http請求體中傳遞文件即可。你應該做的首先是扔掉下面的安全檢查所有代碼在你UploadFile1方法,而是這樣做:

public void UploadFile1(string fileName, Stream input) { 
    // check your security headers here 
    string networkPath = WebConfigurationManager.AppSettings["NetWorkPath"]; 
    using (var fs = File.Create(networkPath + "/" + fileName)) { 
     input.CopyTo(fs); 
    } 
} 

在這裏,我們只是沒有任何緩衝複製輸入流輸出流(文件)(當然CopyTo將緩衝大塊,但它們會很小)。馬克您的服務方法:

[WebInvoke(Method = "POST", UriTemplate = "/UploadFile1/{fileName}")] 

爲了使您在查詢字符串傳遞的文件名。

現在到客戶端。不確定您使用哪種方法與服務器進行通信,我將使用原始HttpWebRequest顯示示例。

var filePath = "path to your zip file here"; 
var file = new FileInfo(filePath); 
// pass file name in query string 
var request = (HttpWebRequest)WebRequest.Create("http://YourServiceUrl/UploadFile1/" + file.Name);    
request.Method = "POST"; 
// set content length 
request.ContentLength = file.Length; 
// stream file to server 
using (var fs = File.OpenRead(file.FullName)) { 
    using (var body = request.GetRequestStream()) { 
     fs.CopyTo(body); 
    } 
} 
// ensure no errors 
request.GetResponse().Dispose(); 
+0

我在編譯wcf服務時遇到錯誤。使用'UriTemplate'的端點不能與'System.ServiceModel.Description.WebScriptEnablingBehavior'一起使用。 –

+0

請參閱:https://blogs.msdn.microsoft.com/justinjsmith/2008/02/15/enablewebscript-uritemplate-and-http-methods/。如果沒有什麼幫助 - 在頭中傳遞文件名而不是查詢字符串。我實際上討厭WCF,因爲那些出現在各處的小問題並沒有多年使用它(並且從未回頭)。 – Evk

+0

我已經通過頭文件中的文件名。 –

相關問題