如果文件比较小,可以像其他人描述的那样使用项目资源文件,但这种方式只能将文件检索为Unicode字符串,可能/很可能比原始文件大两倍,并且一次性全部加载到内存中。
原问题中提到的方法是将文本文件放在项目中的某个位置,在“解决方案资源管理器”中选择它,按F4显示属性,然后将
生成操作设置为
嵌入的资源,并将
复制到输出目录保留为
不复制。
这与添加到.csproj中相同:
<ItemGroup>
<EmbeddedResource Include="Resources\TextFile.txt"/>
</ItemGroup>
那么你需要正确的 Assembly
实例或者一个 IFileProvider
来通过名称访问这些资源。
通过 Assembly:
typeof(Program).Assembly.GetManifestResourceNames()
typeof(Program).Assembly.GetManifestResourceStream(name)
typeof(Program).Assembly.GetManifestResourceInfo(name)
这些名称类似于类名,由点号分隔。如果您的项目是NamespaceName.ProjectName
,资源文件位于Resources
子文件夹中,名为TextFile.txt
,则资源名称将是
NamespaceName.ProjectName.Resources.TextFile.txt
有一个重载版本的GetManifestResourceStream
方法可以接受一个类型参数,你可以这样使用:
typeof(Program).Assembly.GetManifestResourceStream(
typeof(Program),
"Resources.TextFile.txt")
不要依赖默认的命名空间或项目输出文件名。这样做的缺点是它们似乎不能从观察窗口工作。您可能会收到一个异常。
System.ArgumentException "Cannot evaluate a security function."
在这种情况下,只需将代码编写到可以随意执行的地方 - 例如静态方法中。这样,代码将从您的程序集而不是调试器中运行。
并且通过 IFileProvider
:
dotnet add package Microsoft.Extensions.FileProviders.Embedded
using Microsoft.Extensions.FileProviders;
var fp = new EmbeddedFileProvider(typeof(Program).Assembly);
foreach (var fileInfo in fp.GetDirectoryContents(""))
Console.WriteLine($"Name: {fileInfo.Name}, Length: {fileInfo.Length}, ...");
var stream = fp.GetFileInfo("Resources.TextFile.txt").CreateReadStream();
作为一个IFileProvider,您可以尝试从纯嵌入式资源托管.NET Core网站。