How to Read an embedded resource as array of bytes without writing it to disk?

30,261

Solution 1

You are actually already reading the stream to a byte array, why not just stop there?

public static byte[] ExtractResource(String filename)
{
    System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
    using (Stream resFilestream = a.GetManifestResourceStream(filename))
    {
        if (resFilestream == null) return null;
        byte[] ba = new byte[resFilestream.Length];
        resFilestream.Read(ba, 0, ba.Length);
        return ba;
    }
}

edit: See comments for a preferable reading pattern.

Solution 2

Simple alternative using a MemoryStream:

var ms = new MemoryStream();
await resFilestream.CopyToAsync(ms);
var bytes = ms.ToArray();

Solution 3

Keep in mind that Embedded resource filename = Assemblyname.fileName

string fileName = "test.pdf";
System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
string fileName = a.GetName().Name + "." + "test.pdf";

using (Stream resFilestream = a.GetManifestResourceStream(fileName))
{
    if (resFilestream == null) return null;
    byte[] ba = new byte[resFilestream.Length];
    resFilestream.Read(ba, 0, ba.Length);
    var byteArray = ba;
}

Solution 4

if you are reading an embeded resource here is a simple way to do so.

string resourcePath = "pack://application:,,,/resource/location/S_2/{0}";
        StreamResourceInfo resInfo = Application.GetResourceStream(new Uri(resourcePath));

        if (resInfo == null)
        {
            throw new Exception("Resource not found: " + resourcePath);
        }

        var ms = new System.IO.MemoryStream();
        await resInfo.Stream.CopyToAsync(ms);
        byte[] bytes = ms.ToArray();
Share:
30,261
Rafik Bari
Author by

Rafik Bari

StackOverflow is very amazing *)

Updated on September 17, 2021

Comments

  • Rafik Bari
    Rafik Bari over 2 years

    In my application I compile another program from source.cs file using CodeDom.Compiler and I embed some resources ( exe and dll files ) at compile time using :

     // .... rest of code
    
    if (provider.Supports(GeneratorSupport.Resources))
    {
        cp.EmbeddedResources.Add("MyFile.exe");
    }
    if (provider.Supports(GeneratorSupport.Resources))
    {
        cp.EmbeddedResources.Add("New.dll");
    }
    // ....rest of code 
    

    In the compiled file, I need to read the embedded resources as array of bytes. Now I'm doing that by extracting the resources to disk using the function below and the use

    File.ReadAllBytes("extractedfile.exe");
    File.ReadAllBytes("extracteddll.dll");
    

    I do this after extracting the two files to disk using this function :

    public static void ExtractSaveResource(String filename, String location)
    {
        //  Assembly assembly = Assembly.GetExecutingAssembly();
        System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
        // Stream stream = assembly.GetManifestResourceStream("Installer.Properties.mydll.dll"); // or whatever 
        // string my_namespace = a.GetName().Name.ToString();
        Stream resFilestream = a.GetManifestResourceStream(filename);
        if (resFilestream != null)
        {
            BinaryReader br = new BinaryReader(resFilestream);
            FileStream fs = new FileStream(location, FileMode.Create); // say 
            BinaryWriter bw = new BinaryWriter(fs);
            byte[] ba = new byte[resFilestream.Length];
            resFilestream.Read(ba, 0, ba.Length);
            bw.Write(ba);
            br.Close();
            bw.Close();
            resFilestream.Close();
        }
        // this.Close(); 
    }
    

    How can I do the same thing (Get the embedded resources as array of bytes) but without writing anything to hard disk?