当文件名由的ASP.NET Web API控制器确定如何压缩与IIS缓存文件
问题描述:
我与服务可能很大(< 1-200MB)3D模型下面的控制器操作其中存储的ASP.NET Web API JSON格式到磁盘某处(Web根目录外):当文件名由的ASP.NET Web API控制器确定如何压缩与IIS缓存文件
public HttpResponseMessage GetModel(Guid accessToken, Guid modelId)
{
Guid projectId = MyBackend.Validate(accessToken);
string fileName = MyPaths.GetModelFile(projectId, modelId);
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(File.ReadAllText(fileName),
Encoding.UTF8, "application/json");
return response;
}
在我的Global.asax我有这样一行:
GlobalConfiguration.Configuration.MessageHandlers.Insert(
0, new ServerCompressionHandler(new GZipCompressor(), new DeflateCompressor()));
当我调用API端点,如预期的那样内容gzip压缩,但IIS(8.5)不会缓存压缩结果,因此必须重新压缩是每个请求的相关文件。我预计它不会被缓存,因为控制器将JSON读入内存并将其作为StringContent
。
我对IIS几乎一无所知,对ASP.NET Web API一无所知。如何最好地服务JSON文件以便压缩它们并确保IIS缓存压缩结果,以便它们不必每次都重新压缩? (如果这听起来像是某种原因,一个坏主意,我应该宁可做?)
答
我建议创建一个缓存你必须在它的完全控制,而不是委托压缩到IIS或者,在这种情况下,网络API消息处理程序。这是优化CPU使用率以牺牲磁盘空间的最佳方式。
在您的服务器上创建一个目录并保存压缩内容的临时文件。然后,在您的API请求中,检查您的3D模型的压缩文件是否已经创建。如果没有,请立即创建,并将其存储在磁盘上。该模型所要求的结果,下一次将已经被计算,你将只需要返回压缩文件的内容。
// Calculate a path for your cache file.
var compressedCacheFilename = GetCachePath(filename);
Stream compressedStream;
if (File.Exists(compressedCacheFilename)) {
compressedStream = new FileStream(compressedCacheFilename, FileMode.Open, FileAccess.Read);
}
else {
/* Use the best compression algorithm for your data
and store it to the corresponding path. */
compressedStream = compressor.CompressTo(
new FileStream(filename, FileMode.Open, FileAccess.Read),
compressedCacheFilename
);
}
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StreamContent(compressedStream);
response.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
response.Content.Headers.ContentEncoding.Clear();
response.Content.Headers.ContentEncoding.Add("gzip"); // your compression algorithm
注意,在代码示例中,我使用StreamContent
代替StringContent
因为第一使用较少的内存。知道这个假设模型不会改变也很重要。这也可能是你需要磁盘上的最大容量。