如何将逐块字节数组转换为base64字符串?
How to convert chunck by chunck byte array into base64 string?
我们正在读取文件的字节数组并将其转换为 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字符串的解决方案
您在 wcf 服务中使用流输入并不真正意味着您以流方式传递任何内容。事实上在你的情况下你没有,因为:
- 您在内存中缓冲客户端上的整个文件以构建 json 字符串。
- 您通过
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();
我们正在读取文件的字节数组并将其转换为 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字符串的解决方案
您在 wcf 服务中使用流输入并不真正意味着您以流方式传递任何内容。事实上在你的情况下你没有,因为:
- 您在内存中缓冲客户端上的整个文件以构建 json 字符串。
- 您通过
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();