Using File.ReadAllLines from embedded text file

醉酒当歌 提交于 2020-01-23 16:18:06

问题


I have been applying what I have learned so far in Bob Tabors absolute beginners series and I wrote a small console word game for my daughter that requires me to generate a random 5 letter word.

I was previously using File.ReadAllLines(path) to generate a string array from a text file (wordlist.txt) on my system and Random.next to generate the index I would pull from the array.

I learned from some posts here how to embed the file as a resource but now I am unable to find the syntax to point to it (path). Or do I have to access it differently now that it is embedded?

Thanks in advance


回答1:


Without a good, minimal, complete code example it is impossible to offer specific advice.

However, the basic issue is this: when you embed a file as a resource, it is no longer a file. That is, the original file still exists, but the resource itself is not a file in any way. It is stored as some specific kind of data in your assembly; resources embedded from file sources generally wind up as binary data objects.

How to use this data depends on what you mean by "embed". There are actually two common ways to store resources in a C# program: you can use the "Resources" object in the project, which exposes the resource via the project's ...Properties.Resources class (which in turn uses the ResourceManager class in .NET). Or you can simply add the file to the project itself, and select the "Embedded Resource" build option.

If you are using the "Resources" designer, then there are a couple of different ways you might have added the file. One is to use the "New Text File..." option, which allows you to essentially copy/paste or type new text into a resource. This is exposed in code as a string property on the Properties.Resources object. The same thing will happen if you add the resource using the "Existing File..." option and select a file that Visual Studio recognizes as a text file.

Otherwise, the file will be included as a byte[] object exposed by a property in the Properties.Resources class.

If you have used the "Embedded Resource" build option instead of the "Resources" designer, then your data will be available by calling Assembly.GetManifestResourceStream(string) method, which returns a Stream object. This can be wrapped in StreamReader to allow it to be read line-by-line.

Direct replacements for the File.ReadAllLines(string) approach would look something like the following…

Using "Embedded Resource":

string[] ReadAllResourceLines(string resourceName)
{
    using (Stream stream = Assembly.GetEntryAssembly()
        .GetManifestResourceStream(resourceName))
    using (StreamReader reader = new StreamReader(stream))
    {
        return EnumerateLines(reader).ToArray();
    }
}

IEnumerable<string> EnumerateLines(TextReader reader)
{
    string line;

    while ((line = reader.ReadLine()) != null)
    {
        yield return line;
    }
}

Using Properties.Resources:

You can do something similar when using the Properties.Resources class. It looks almost identical:

string[] ReadAllResourceLines(string resourceText)
{
    using (StringReader reader = new StringReader(resourceText))
    {
        return EnumerateLines(reader).ToArray();
    }
}

called like string[] allLines = ReadAllResourceLines(Properties.Resources.MyTextFile);, where MyTextFile is the property name for the resource you added in the designer (i.e. the string you pass in that second example is the text of the file itself, not the name of the resource).

If you added an existing file that Visual Studio didn't recognize as a text file, then the property type will be byte[] instead of string and you'll need yet another slightly different approach:

string[] ReadAllResourceLines(byte[] resourceData)
{
    using (Stream stream = new MemoryStream(resourceData))
    using (StreamReader reader = new StreamReader(stream))
    {
        return EnumerateLines(reader).ToArray();
    }
}

Note that in all three examples, the key is that the data winds up wrapped in a TextReader implementation, which is then used to read each line individually, to populate an array. These all use the same EnumerateLines() helper method I show above.

Of course, now that you see how the data can be retrieved, you can adapt that to use the data in a variety of other ways, in case for example you don't really want or need the text represented as an array of string objects.




回答2:


If you are using The Resource file and added a text file you could use

string text=Properties.Resources.<ResourceName>

here Resources is default Resource for your project .If you have added a custom Resource File you can use its name instead of Properties.Resources

if your content is a file then it is represented as a byte.In your case for simple Text it will be an string if you have included a Text File.

for any other file you can use the syntax for converting content to text(if it is text) as

string text=Encoding.ASCII.GetString(Properties.Resources.<ResourceName>);

if your file has any other encoding (as UTF Unicode ) you can use UTF8 or such classes for that under Encoding



来源:https://stackoverflow.com/questions/29910061/using-file-readalllines-from-embedded-text-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!