C# 将大字符串转换为UTF-8
我有一个WCF4REST服务,它查询数据库并返回JSON。有些用户希望进行非常大的查询,尽管我很难返回字符串。例如,我需要返回一个500M JSON字符串(所有数据都是ASCII文本),但当我尝试从.NET的本机UTF-16转换字符串时,遇到了OutOfMemoryException。这是我正在做的一个简单的例子C# 将大字符串转换为UTF-8,c#,wcf,rest,utf-8,C#,Wcf,Rest,Utf 8,我有一个WCF4REST服务,它查询数据库并返回JSON。有些用户希望进行非常大的查询,尽管我很难返回字符串。例如,我需要返回一个500M JSON字符串(所有数据都是ASCII文本),但当我尝试从.NET的本机UTF-16转换字符串时,遇到了OutOfMemoryException。这是我正在做的一个简单的例子 [WebInvoke(UriTemplate="/RunQuery", ResponseFormat=WebMessageFormat.Json)] public Stream Run
[WebInvoke(UriTemplate="/RunQuery", ResponseFormat=WebMessageFormat.Json)]
public Stream RunQuery() {
// Perform query and return serialized json string (~500 million ASCII characters)
string json = DoQuery(HttpContext.Current.Request.Form);
// Set output charset
WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";
// Convert UTF-16 string to UTF-8 (OutOfMemoryException)
byte jsonBytes[] = System.Text.Encoding.UTF8.GetBytes(json)
// Send UTF-8 string, without BOM
return new MemoryStream(jsonBytes);
}
只有当我将JSON保持在200M左右时,它才起作用。当它运行时,我看到IIS进程的内存使用率逐渐上升,然后爆炸到2.8G,在这一点上它就死了。stacktrace报告它发生在System.String.ToCharray。我尝试过对字符串进行分块以构建字节数组,但似乎没有任何效果。你知道我如何在不爆炸的情况下发送这些数据吗?你可以通过编写自己的实现来解决这个问题,该实现可以动态地将输入转换为utf8 您应该能够通过提取输入字符串的一部分,将它们逐块转换为utf 8来实现这一点
请记住,字节数不一定与字符数完全相同,除非您从未发送任何类型的国际字符 如果必须返回流,请使用文件流或至少预先分配内存流空间 如果必须使用500Mb字符串:
- 使用64位机器和64位进程。x86进程不太可能成功分配2个这样大小的内存。请注意,即使您使用64位进程,CLR对“单块分配”大小的限制约为2Gb,这使得1Gb字符串不太可能适合内存。因此,在500Mb-1Gb附近的某个点上,切换到64位将不再有用
- 使用编写器-在将JSON写入输出时,编写器可以轻松(即)直接编码到输出。作为补充建议,不要创建JSON字符串,而是将输出写入Writer
- 如果您知道您的字符串仅为ASCII码,那么您可以通过将每个字符转换为字节来编写流来作弊