none
GetManifestResourceStream method RRS feed

  • Question

  • Assembly _assembly;
      _assembly = Assembly.GetExecutingAssembly();
      StreamReader fileStream;
           
           
            try
            {
               
                fileStream = new StreamReader(_assembly.GetManifestResourceStream("GlobalResourceTest.Test.resx"));
            }
            catch
            {
              
            }

     I am trying to access the resx file from memory, but fileStream is always null, why?
    Friday, April 24, 2009 6:29 AM

Answers

  • This sounds familiar.  Your program is always reading disk data from a cache.  The file system cache.  The CLR caches some manifest data as well.  It is pretty unlikely you'll be able to measure a difference.

    Hans Passant.
    • Marked as answer by N.Afache Tuesday, April 28, 2009 2:40 PM
    Friday, April 24, 2009 1:30 PM
    Moderator

All replies

  • The new operator never returns null. It either succeeds or throws an exception. If you remove the catch block (or set your debugger to break when exceptions are thrown) it will probably give you an idea of why it's failing.
    Mattias, C# MVP
    Friday, April 24, 2009 6:37 AM
  • Value cannot be null.
    Parameter name: stream

    which means that:   _assembly.GetManifestResourceStream("GlobalResourceTest.Test.resx") is returning a null value.
    Friday, April 24, 2009 6:45 AM
  • Hi,

    assemble.GetManifestResourceStream(string) will return the resource from the resource file (.resx file) for that assemble. The parameter passed to this should be the name of the embed resource in the resource file. For more details see the following links

    http://www.attilan.com/2006/08/accessing_embedded_resources_u.php
    http://msdn.microsoft.com/en-us/library/system.reflection.assembly.getmanifestresourcestream.aspx
    http://support.microsoft.com/kb/319292

    As you are passing the resource file name itself and it is not embed in the resource file, it returns null. If you have a resource embed in the resource file with the same name ( "GlobalResourceTest.Test.resx" )then you will get the stream.

    Thanks and regards,
    Vijay Pandurangan
    Friday, April 24, 2009 7:10 AM
  • Hi,
      I don't see a buildAction property for .resx files in the property window.
    Friday, April 24, 2009 7:31 AM
  • The Resource file won't have a build action rather it will be included in the compilation process if a resource file exist.

    See http://msdn.microsoft.com/en-us/library/6s2x2bzy.aspx for the compilation switch to include resource file. (in IDE this will be retrieved from proj file).

    See http://msdn.microsoft.com/en-us/library/aa380599(VS.85).aspx for the details about resource files.

    Also http://support.microsoft.com/kb/917414 for effective resource file handling

    Thanks and regards,
    Vijay Pandurangan
    Friday, April 24, 2009 7:38 AM
  • My resx file name is Test. I have written the code below and it works. GetString works well. But Getstream does not.
    The parameter for the GetStream method is the name of the resource, but memStream is returned as null. why do you think?


    ResourceManager _resourceManager = new ResourceManager("Resources.Test", Assembly.Load("app_globalresources"));
                String str = _resourceManager.GetString("Naji");
                memStream = _resourceManager.GetStream("Test");

    Friday, April 24, 2009 8:55 AM
  • I hope in your resource file you have stored a string value with key "Naji", hence the GetString returns the value.


    In the GetStream method, you should not pass the resource file (resx) name. You should pass the embedded object (can be file, dll, pictures etc) name.

    To add resources in resource file, open the resource file, by default it will open the grid with three columns "Name", "Value" and "Comment" - this screen is for adding/managing the strings in the resource file which can be read through GetString() method with the "Name" column value.
    To add the files, click the small arrow near "Add Resources" button (will be in the top of the opened resource file) you can see "Add Existing File", "Add New Sring", "New Image" (which have the sub menu for PNG, JPEG, GIF, TIFF and BMP files) and "Add new text file".
     
    Say for instance you added a image file in the resource (resx), by defaut the name of the resource will be the name of the "nameofthefile" (spaces will be _)will be the file name, and for image files the name of the file alone will be the name. You can rename it.

    These resources can be accessed throuh GetStream() method by specifing the name in the resource file.

    You can't read the resource file itself through the GetStream() method. You can read them directly by using FileReaders (xml is suggested) by specifiing absolute path or relative path. But even when you read them directly you can't access those resource. Actually the resources (image or any type of files) will be added to the Resource Directory and when the project is compiled, the referred files will be embedded in to the assembly, hence you won't find those file outsite but still from the application you can access them through GetStream method.

    Thanks and regards,
    Vijay Pandurangan.

    Friday, April 24, 2009 9:51 AM
  • You probably got the resource name wrong.  Run Ildasm.exe on your assembly and double-click Manifest.  You'll see the names of the resources.

    Hans Passant.
    Friday, April 24, 2009 11:13 AM
    Moderator
  • The code below works. I have one final question for you. When I use GetManifestResourceStream I am reading data from cache and not from disk, is that correct? Would that be considered more efficient than reading from the disk since the cached data is already in memory?
     Assembly _assembly;
          
            try
            {
     
                _assembly = Assembly.Load("app_globalresources");
                string[] names = _assembly.GetManifestResourceNames();
                IResourceReader reader = new ResourceReader(_assembly.GetManifestResourceStream("resources.test.resources"));
                DataTable dt = new DataTable();
                dt.Columns.Add("key");
                dt.Columns.Add("Value");

                foreach (DictionaryEntry d in reader)
                {

                  
                    DataRow dr = dt.NewRow();
                    dr[0] = d.Key.ToString();
                    dr[1] = d.Value.ToString();
                    dt.Rows.Add(dr);
                }

                //Close the resxReader

                reader.Close();
             
            }
            catch
            {
              
            }

    Friday, April 24, 2009 11:31 AM
  • This sounds familiar.  Your program is always reading disk data from a cache.  The file system cache.  The CLR caches some manifest data as well.  It is pretty unlikely you'll be able to measure a difference.

    Hans Passant.
    • Marked as answer by N.Afache Tuesday, April 28, 2009 2:40 PM
    Friday, April 24, 2009 1:30 PM
    Moderator