4

I have embed sample.txt(it contains just one line "aaaa" ) file into project's resources like in this answer. When I'm trying to read it like this:

string s = File.ReadAllText(global::ConsoleApplication.Properties.Resources.sample);

I'm getting System.IO.FileNotFoundException' exception. Additional information: Could not find file 'd:\Work\Projects\MyTests\ConsoleApplication\ConsoleApplication\bin\Debug\aaaa'.

So seemingly it's trying to take file name from my resource file instead of reading this file. Why is this happening? And how can I make it read sample.txt

Trying solution of @Ryios and getting Argument null exception

  using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ConsoleApplication.Resources.sample.txt"))
        {
            TextReader tr = new StreamReader(stream);
            string fileContents = tr.ReadToEnd();
        }

The file is located in d:\Work\Projects\MyTests\ConsoleApplication\ConsoleApplication\Resources\sample.txt

p.s. Solved. I had to set Build Action - embed resource in sample.txt properties

Community
  • 1
  • 1
Dork
  • 1,816
  • 9
  • 29
  • 57
  • Can you show us the string stored in the sample parameter? It would appear to have some illegal characters for a file path. – ManoDestra Mar 03 '16 at 18:30
  • What happens if you drop the global:: part from that – BugFinder Mar 03 '16 at 18:30
  • Unless you are locked into using the Resource file, you may want to embed the file as in http://stackoverflow.com/questions/3314140/how-to-read-embedded-resource-text-file?rq=1 instead. It's easier to maintain. – Michael Bray Mar 03 '16 at 18:34
  • sorry, I edited question to make problem clearer. – Dork Mar 03 '16 at 18:40
  • Just use a string setting in your project, then read that setting and read the file. – ManoDestra Mar 03 '16 at 19:04
  • @ManoDestra please elaborate – Dork Mar 03 '16 at 19:07
  • Go to your project's Settings and add a String setting (called say FileToRead) and enter the path of the file you wish to read into that setting. Then get your program to simple read from Properties.Settings.Default.FileToRead. Then, just read from the file with that specified path stored in that setting. That's really what you're looking for here, I think. – ManoDestra Mar 03 '16 at 19:15
  • Or just make the file part of your project and make it copy to the bin folder on build. That way you'll have a guaranteed file existing and a guaranteed path to access it. Either way is good. – ManoDestra Mar 03 '16 at 19:16

2 Answers2

12

You can't read Resource Files with File.ReadAllText.

Instead you need to open a Resource Stream with Assembly.GetManifestResourceStream.

You don't pass it a path either, you pass it a namespace. The namespace of the file will be the Assemblies Default Namespace + The folder heieracy in the project the file is in + the name of the file.

Imagine this structure

  • Project (xyz.project)
    • Folder1
      • Folder2
        • SomeFile.Txt

So the namespace for the file will be:

xyz.project.Folder1.Folder2.SomeFile.Txt

Then you would read it like so

        using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("xyz.project.Folder1.Folder2.SomeFile.Txt"))
        {
            TextReader tr = new StreamReader(stream);
            string fileContents = tr.ReadToEnd();
        }
Ryan Mann
  • 5,178
  • 32
  • 42
6

Hello the proposed solution doesn't work

This return null:

Assembly.GetExecutingAssembly().GetManifestResourceStream("xyz.project.Folder1.Folder2.SomeFile.Txt")

Another way is to use a MemoryStream from the Ressource Data:

  byte[] aa = Properties.Resources.YOURRESSOURCENAME;
  MemoryStream MS =new MemoryStream(aa);
  StreamReader sr = new StreamReader(MS);

Not ideal but it works

H. Pauwelyn
  • 13,575
  • 26
  • 81
  • 144