.NET Core项目Docker容器中CSV文件访问异常求助
嘿,我碰到过几乎一模一样的坑!问题根源很明确:你的testdata.csv文件没被打包到发布后的Docker镜像里——调试时你在项目目录跑程序,文件就在根目录下所以能找到,但发布后输出目录里压根没这个文件,容器自然就报找不到了。
下面是一步步的解决办法:
1. 让CSV文件随发布流程自动复制
首先得修改你的项目文件(PVT_Matching_Algorithm.csproj),告诉.NET在发布时把这个CSV文件带过去。打开项目文件,添加这段配置:
<ItemGroup> <None Update="Data\testdata.csv"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup>
这段配置的作用是:标记Data\testdata.csv文件,让它在编译和发布时自动复制到输出目录,而且只会在文件有更新时才复制,避免重复操作。
2. 修正代码里的路径获取逻辑
你现在用的相对路径Path.Combine("Data", fileName)在调试时没问题,但发布后程序的工作目录可能和你预期的不一样。在.NET Core里,应该用程序集的基目录来构建路径,这样不管在哪运行都不会出错:
[Route("GetTestFile")] [HttpGet] public IActionResult GetTestFile() { var fileName = "testdata.csv"; // 获取程序运行的根目录(Docker容器里就是/app目录) var baseDirectory = AppContext.BaseDirectory; var filePath = Path.Combine(baseDirectory, "Data", fileName); return new FileContentResult(File.ReadAllBytes(filePath), "text/csv") { FileDownloadName = fileName }; }
AppContext.BaseDirectory会返回你的程序集所在的目录,也就是Docker容器里的/app文件夹,用这个路径组合出来的文件地址绝对是正确的。
3. 重新构建Docker镜像
最后清理掉旧的容器和镜像,重新构建运行:
# 停止并删除旧容器(如果正在运行) docker stop pvt-matching-container docker rm pvt-matching-container # 删除旧镜像 docker rmi pvt-matching # 重新构建镜像 docker build -t pvt-matching . # 启动新容器 docker run -d -p 80:80 --name pvt-matching-container pvt-matching
为啥调试时没问题?
调试模式下,程序直接在项目根目录运行,Data文件夹就在根目录里,所以相对路径能找到文件。但发布后,程序会被打包到输出目录(比如bin/Release/netcoreapp2.0/publish),如果没配置复制文件,Data文件夹和CSV不会被自动复制过去,Docker镜像里的/app目录自然就没有这个文件,所以会抛出FileNotFoundException。
内容的提问来源于stack exchange,提问作者ajs117

