When I use GetManifestResourceStream
to retrieve an embedded resource from a .NET assembly, what kind of I/O is involved?
I see two possibilities:
The entire assembly was already put into memory when .NET loaded it, so GetManifestResourceStream
is just accessing memory.
Only the code parts of the assembly were put into memory when the assembly was loaded by .NET, so GetManifestResourceStream
needs to go back to the .dll
file to extract the embedded resource.
I'm pretty sure the first is the case, especially since assemblies can be loaded dynamically from raw data with Assembly.Load(Byte[])
. But then I wonder what happens if a very large file (say several gigabytes) was embedded - the second option might be more efficient. Does size matter?
Just challenging some long-held assumptions, and not able to find much in the way of reference on this.
resources) file by using Resource File Generator (resgen.exe). You can then embed the . resources file in a . NET assembly by using a language compiler or embed it in a satellite assembly by using Assembly Linker (Al.exe).
Embedded files are called as Embedded Resources and these files can be accessed at runtime using the Assembly class of the System.Reflection namespace. This article will illustrate, how to read and display an embedded Text file and Image file in Windows Application (Windows Forms) in C# and VB.Net.
Open Solution Explorer add files you want to embed. Right click on the files then click on Properties . In Properties window and change Build Action to Embedded Resource . After that you should write the embedded resources to file in order to be able to run it.
Embedded resource has no predefined structure: it is just a named blob of bytes. So called “. resx” file is a special kind of embedded resource. It is a string -to-object dictionary that maps a name to an object. The object may be a string , an image, an icon, or a blob of bytes.
"Memory" is not a precise enough term on a demand-paged virtual memory operating system like Windows, Linux, MacOS. The CLR maps the assembly into the address space of the process using a memory-mapped file (MMF). Just numbers to the processor, one each for every 4096 bytes. Nothing is read from the file just yet.
That is delayed until the program tries to read from an address inside the address space. First access generates a page fault, the kernel allocates RAM for the page and fills it with the file content. After which the program resumes as though nothing happened. Strongly empowers the "you don't pay for what you don't use" advantage of virtual memory.
There is no "extraction", you are reading the resource data directly from memory, most efficient way it could have been implemented. An embedded resource does not otherwise behave any differently from other data in the file, like the metadata and the MSIL. You likewise don't pay for any code in the assembly that you never call.
Do keep in mind that an embedded resource occupies the same OS resource as the GC heap, it too requires address space. Only real difference is that GC heap address space is backed by the OS paging file and can never be shared with other processes, the assembly data is backed by the assembly file and can be shared. Large resources notably shrink the amount of memory you can allocate in a .NET program, even if you never use them. That matters only in a 32-bit process, a 64-bit process has many terabytes of address space.
Another restriction is that an MMF view can never be larger than 2 GB, even in a 64-bit process, that sets a hard upper limit on the maximum size of a resource. That usually keels over very early, failing the build with CS1566, "Specified argument was out of the range of valid values". Not a great diagnostic btw.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With