If the file is small, the project resource file can be used as described by others, but that way the file can only be retrieved as an Unicode string, potentially/probably twice larger than the original file and loaded into memory at once in its entirety.
The way referred to in the original question is to just put the text file somewhere in your project, select it in Solution Explorer, hit F4 to show Properties, then set Build Action to Embedded resource and leaving Copy to output directory at Do not copy.
This is the same as adding to your .csproj:
<ItemGroup>
<EmbeddedResource Include="Resources\TextFile.txt"/>
</ItemGroup>
Then you will need either an instance of the correct Assembly
, or an IFileProvider
to access those resources by name.
Through Assembly:
typeof(Program).Assembly.GetManifestResourceNames()
typeof(Program).Assembly.GetManifestResourceStream(name)
typeof(Program).Assembly.GetManifestResourceInfo(name)
these names are akin class names, dot-separated. If your project is NamespaceName.ProjectName
, the resource file is in the Resources
subfolder and called TextFile.txt
, the resource name is going to be
NamespaceName.ProjectName.Resources.TextFile.txt
There is an overload for GetManifestResourceStream
that takes a type so you can do
typeof(Program).Assembly.GetManifestResourceStream(
typeof(Program),
"Resources.TextFile.txt")
to never depend on the default namespace or project output file name.
The downside to these is that they don't appear to work from the watches window. You might get an exception
System.ArgumentException "Cannot evaluate a security function."
In that case just write that code some place where you can execute it at will - in a static method for example. So that code runs from your assembly, not the debugger.
And through 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();
Being an IFileProvider
, you could probably try to host .NET Core websites from pure embedded resources.