Visual Studio中C#服务不写本地磁盘缓存HttpWebRequest文件方案咨询
实现方案
你可以从以下三种可落地的方案中选择符合你当前技术栈的实现:
方案1:使用分布式缓存(推荐,适合中等体积文件,访问性能最优)
选择Redis作为缓存存储介质,天然支持跨机器共享、持久化存储,无需依赖本地磁盘权限。你可以引入StackExchange.RedisNuGet包实现操作,修改后逻辑如下:// 初始化Redis连接(建议单例注入,不要每次请求新建) var redis = ConnectionMultiplexer.Connect("你的Redis连接串"); var db = redis.GetDatabase(); // 缓存key建议和_fileHeader绑定,区分不同版本的文件 string cacheKey = $"IinFile:Cache:{_fileHeader}"; // 启动时先读缓存 string responseContent = await db.StringGetAsync(cacheKey); if (string.IsNullOrEmpty(responseContent)) { // 缓存不存在,走原有请求逻辑 HttpWebRequest request = (HttpWebRequest)WebRequest.Create( _options.CurrentValue.HttpWebRequest+"/GetFile/GetLatestFileForIinService?header=" + _fileHeader); _options.OnChange((options) => { request = (HttpWebRequest)WebRequest.Create( options.HttpWebRequest + "/GetFile/GetLatestFileForIinService?header=" + _fileHeader); }); request.Method = "GET"; request.AllowAutoRedirect = false; request.Accept = "*/*"; request.ContentType = "text/csv"; request.Headers.Add("Content-Disposition", "attachment; filename=IinRanges-2021119.csv"); using WebResponse response = request.GetResponse(); using Stream stream = response.GetResponseStream(); if (stream == null) return; using StreamReader sr99 = new(stream, Encoding.ASCII); responseContent = sr99.ReadToEnd(); // 写入缓存,可根据文件更新频率自定义过期时间 await db.StringSetAsync(cacheKey, responseContent, TimeSpan.FromHours(24)); } // 后续直接使用responseContent即可可以额外存储文件的ETag或MD5值到缓存,下次请求时携带
If-None-Match头,服务端返回304状态码时直接复用缓存内容,无需全量拉取。方案2:使用配置中心存储(适合小体积文件,无需额外引入组件)
如果你当前服务已经接入了Apollo、Nacos等配置中心,可以直接将文件内容作为配置项存储在配置中心,本身支持跨机器同步、持久化,你只需要调用配置中心的写入、读取接口即可,不需要额外申请存储资源。方案3:使用业务数据库存储(适合所有场景,改造成本最低)
新增一张简单的文件缓存表,字段包含缓存key、文件内容、过期时间、哈希校验值,请求文件前先查表中是否存在有效缓存,存在则直接读取使用,不存在则请求完成后写入表中。
内容的提问来源于stack exchange,提问作者Mubeen Khan
相关产品推荐
相关产品推荐

