[英]Sent large base64string into jsonbody
我使用弹性搜索进行一些集成。 我需要将一个很大的文件转换为base64string。 转换后,我需要将其发送给ES。 下面是我的代码。
public IRestResponse ESMapFileAttachment(string indexName, string mappingName, string fileIndex, string fileName, Byte[] fileBytes)
{
var client = new RestClient(string.Format("{0}{1}/{2}/{3}", ConfigurationManager.AppSettings["esserver"], indexName, mappingName, fileIndex));
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
string encodedFileContent = Convert.ToBase64String(fileBytes); // got out of memory exception here
var jsonString = @"
{
""file"": {
""_content"": ""XEncodedFileContentX"",
""_name"": ""XFilenameX"",
""_detect_language"": true,
""_indexed_chars"": -1
}
}
".Replace("XEncodedFileContentX", encodedFileContent)
.Replace("XFilenameX", fileName);
var jsSerializer = new JavaScriptSerializer();
jsSerializer.MaxJsonLength = Int32.MaxValue;
var jObject = jsSerializer.DeserializeObject(jsonString);
request.AddJsonBody(jObject);
return client.Execute(request);
}
但是当我尝试将其转换为base64string时,却以某种方式得到了“内存不足”异常。 我已经尝试了10Mb以下的文件,并且效果很好。 但是当它真的很大时,即使是大约100Mb,我也例外,即使我的PC是8GB RAM。
Base64会占用您输入的3个字节,并在输出时将其转换为4个字节的文本。 这对您有好处,因为这意味着您可以占用一小部分输入数据并进行base64转换,然后可以接下一部分输入数据并进行base64转换,并将base64操作的第二个输出附加到第一个,您将获得与立即转换整个对象相同的结果。
因此,解决您的问题的方法是采用固定大小的缓冲区,该缓冲区可以被3整除,例如3 * 1024 * 1024字节。 您将在每轮中使用它来转换3 MB的输入数据。 在每个回合之后,您都可以将其附加到StringBuilder,然后便可以创建想要的较大结果。
话虽如此,我不确定你会怎么做
.Replace("XEncodedFileContentX", encodedFileContent)
原因是什么时候encodedFileContent将具有该大小。 您可能还需要找到该部分的替代方法...
如果需要将整个文件存储在内存中,则需要将目标平台更改为x64。 另一种方法是使用较小的部分转换文件。 用于UTF8编码的字符每个字符最多可占用4个字节。 我运行一个示例应用程序来转换170MB二进制文件,将其转换为226.000个字符的字符串,应用程序消耗了大约1GB的RAM。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.