如果文件很小,则可以按照其他人的描述使用项目资源文件,但是这样只能将文件作为 Unicode 字符串检索,可能/可能比原始文件大两倍,并立即将其全部加载到内存中.
原始问题中提到的方法是将文本文件放在项目中的某个位置,在解决方案资源管理器中选择它,按 F4 以显示属性,然后将Build Action设置为Embedded resource并将Copy to output directory保留为Do not copy。
这与添加到 .csproj 相同:
<ItemGroup>
<EmbeddedResource Include="Resources\TextFile.txt"/>
</ItemGroup>
然后,您将需要一个正确的实例Assembly
,或者一个IFileProvider
按名称访问这些资源的实例。
通过组装:
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);
// get all resources as an enumerable
foreach (var fileInfo in fp.GetDirectoryContents(""))
Console.WriteLine($"Name: {fileInfo.Name}, Length: {fileInfo.Length}, ...");
// get a specific one by name
var stream = fp.GetFileInfo("Resources.TextFile.txt").CreateReadStream();
作为IFileProvider
.NET Core 网站,您可能会尝试从纯嵌入式资源托管。