2016-05-12 27 views
1

我々は、ファイルのバイト配列を読み取り、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 + "\"}"; 

を次のように我々はそれがメモリ不足の例外投げされ、base64文字列に1ギガバイト点で最大サイズの大きいファイルを変換しようとするbase64文字列に変換されます。私たちはこのjsonを安らかな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 
     } 

本当にあなたがストリーミングされた方法で何かを渡すという意味ではありません、あなたのWCFサービスにbase64文字列

+0

1GBのbase64でエンコードされた文字列をjsonとして送信するのは良い考えではありません。 – Evk

+0

@Evkコメントありがとうございました。私たちはアンドロイドモバイルアプリケーションとウェブアプリケーションを使ってファイルをアップロードしています。ファイルシステム上のリモートサーバーにファイルをアップロードしています。なので、ファイルをアップロードするためにRESTFul wcfサービスを書いたのですが –

+0

しかし、私の場合、ファイルが大きくて(10MB以上)、jsonで直列化されたものを渡すべきではありません。あなたはストリーミング方式でリクエストボディにそれらを渡す必要があります。これはRESTful wcfサービスにも当てはまります。私はチャンクでbyte []チャンクをbase64に変換する方法を示していたかもしれませんが、それはあなたには役に立たないでしょう。 – Evk

答えて

2

にあなたはストリーム入力を使用することを大きなバイト配列に変換するためのソリューションを提供してください。あなたは、JSON文字列を構築するためにメモリにクライアント上のファイル全体をバッファ

  1. :ので、あなたのケースでは実際には、あなたは、しないでください。
  2. stmRequest.ReadToEnd()を経由して、サーバー上のファイル全体をメモリにバッファリングします。

ストリーミングは発生しません。最初に、ここではjsonが必要ないことを認識する必要があります.HTMLリクエスト本体にファイルを渡すだけです。あなたが最初にすべきことはあなたの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}")] 

クエリ文字列にfilenameを渡すことを許可します。

Now to client。どのメソッドを使ってサーバーと通信するのかわからないので、生の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

ヘッダーにファイル名を渡しました。 –

関連する問題