Docker+ASP.NET Core+C#:如何解决容器中无法读取输入文件的问题?
解决Docker容器中C#程序读取Advent of Code输入文件的问题
问题根源
你硬编码了Windows绝对路径C:\\work\\VisualAdventOfCode\\APIAdventOfCode\\Puzzles\\" + inputPath,Docker容器默认是Linux环境,路径格式不兼容且容器内不存在该目录,导致文件找不到。
规范解决方案
以下是适配本地开发和Docker部署的标准做法:
1. 配置输入文件自动复制到输出目录
在你的C#项目(APIAdventOfCode)中,确保输入文件会随编译过程复制到输出目录:
- 手动操作:选中Puzzles目录下的所有
.txt文件,右键→属性,将「复制到输出目录」设置为「如果较新则复制」或「始终复制」。 - 或编辑
.csproj文件,添加以下配置(批量高效):
这样编译后,输入文件会被复制到<ItemGroup> <None Include="Puzzles\**\*.txt" CopyToOutputDirectory="PreserveNewest" /> </ItemGroup>bin/[Debug/Release]/netX/Puzzles/目录,Docker构建时也会包含这些文件。
2. 修改代码使用相对路径读取
替换硬编码的绝对路径,基于程序运行目录动态拼接路径:
public static IEnumerable<string> ReadStringInput(string inputPath) { // 获取程序当前运行的基准目录 string baseDirectory = AppContext.BaseDirectory; // 用Path.Combine自动适配不同系统的路径分隔符 string inputFilePath = Path.Combine(baseDirectory, "Puzzles", inputPath); // 可选:调试时输出实际路径,方便排查问题 Console.WriteLine($"Reading input from: {inputFilePath}"); return File.ReadLines(inputFilePath); }
注意:这里的inputPath应该是相对于Puzzles目录的路径(比如"_2022/Input/OneInput.txt"),不需要带根路径。
3. 确保Dockerfile正确复制发布文件
使用.NET官方镜像的Dockerfile要保证发布阶段包含所有输出文件,示例如下:
# 构建阶段:编译项目 FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build WORKDIR /src COPY ["APIAdventOfCode/APIAdventOfCode.csproj", "APIAdventOfCode/"] RUN dotnet restore "APIAdventOfCode/APIAdventOfCode.csproj" COPY . . WORKDIR "/src/APIAdventOfCode" RUN dotnet build "APIAdventOfCode.csproj" -c Release -o /app/build # 发布阶段:生成部署包 FROM build AS publish RUN dotnet publish "APIAdventOfCode.csproj" -c Release -o /app/publish /p:UseAppHost=false # 运行阶段:启动应用 FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "APIAdventOfCode.dll"]
dotnet publish会把之前配置的Puzzles文件一起打包到/app/publish目录,容器运行时WORKDIR为/app,代码中的相对路径就能正确定位到文件。
4. 验证路径正确性
运行容器时查看日志,确认输出的文件路径是否为/app/Puzzles/_2022/Input/OneInput.txt这类格式,确保与容器内实际文件位置一致。
内容的提问来源于stack exchange,提问作者Tim L
相关产品推荐
相关产品推荐

