2016-05-12 19 views
1

Wir Byte-Array einer Datei zu lesen und es in base64 String Umwandlung alsWie chunck von Chunck Byte-Array in Base64-String konvertieren?

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 + "\"}"; 

folgen Wenn wir versuchen, bis zu 1 GB in base64 String große Datei zu konvertieren, wird es aus der Erinnerung Ausnahme werfen. Wir senden diese JSON zu einem erholsamen Service. Folgendes ist meine Methode in RESTful WCF Service.

[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 
     } 

Bitte geben Lösung für die Konvertierung großes Byte-Array in base64 String

+0

Senden 1GB Base64-codierte Zeichenfolge als JSON ist keine sehr gute Idee, meinst du nicht? – Evk

+0

@Evk Danke für den Kommentar. Wir verwenden Android mobile Anwendungen und Webanwendungen zum Hochladen von Dateien. Wir laden Datei auf einen Remote-Server im Dateisystem hoch. Deshalb habe ich geschrieben RESTFul WCF-Service zum Hochladen von Datei –

+0

Aber ich meine - wenn Ihre Dateien groß sind (mehr als sagen 10MB) - sollten Sie sie nie serialisiert in JSON übergeben. Sie müssen sie im Anfragetext streamweise übergeben. Dies gilt auch für RESTful-WCF-Dienste. Ich hätte zeigen können, wie man byte [] chunk by chunk in base64 konvertiert, aber das würde _not_ nicht helfen. – Evk

Antwort

2

Die Tatsache, Sie Stream-Eingang in Ihrem Wcf-Dienst verwenden, bedeutet nicht wirklich Sie etwas in gestreamten Weise passieren. In der Tat in Ihrem Fall nicht, weil:

  1. Sie Puffer ganze Datei auf Client im Speicher, um JSON-String zu bauen.
  2. Sie puffern ganze Datei auf Server im Speicher über stmRequest.ReadToEnd().

So findet kein Streaming statt. Zuerst sollten Sie feststellen, dass hier kein Json benötigt wird - Sie müssen lediglich die Datei in Ihrem http-Anfragekörper übergeben. Was sollten Sie tun, ist der gesamte Code unter Sicherheitskontrollen wegzuwerfen in Ihrem UploadFile1 Methode und stattdessen tun:

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

Hier wir Eingangsstrom einfach kopieren zu Ausgangsstrom (Datei) ohne Pufferung (natürlich CopyTo puffert Brocken, aber sie werden sehr klein sein). Markieren Sie Ihre Service-Methode mit:

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

Damit Sie Dateinamen in Query-String übergeben können.

Jetzt zum Client. Nicht sicher, welche Methode Sie verwenden, um mit Server zu kommunizieren, zeige ich Beispiel mit roher 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

Ich bekomme Fehler beim Kompilieren von WCF-Service. Endpoints, die 'UriTemplate' verwenden, können nicht mit 'System.ServiceModel.Description.WebScriptEnablingBehavior' verwendet werden. –

+0

Siehe hier: https://blogs.msdn.microsoft.com/justinsmith/2008/02/15/enablewebscript-uritemplate-and-http-methods/. Wenn nichts hilft - übergeben Sie den Dateinamen im Header anstelle der Abfragezeichenfolge. Ich hasse WCF wegen dieser winzigen Probleme, die überall auftauchen und sie seit Jahren nicht mehr benutzt haben (und nie zurückgeschaut haben). – Evk

+0

Ich habe den Dateinamen im Header übergeben. –