C# Read text file from resources rather than locally 错误,添加命名空间不起作用

C# Read text file from resources rather than locally error, adding namespace didnt work

我在这里尝试了多种解决方案,但没有一个我可以开始工作。我只想从我的资源文件夹而不是实际的本地文件夹中读取一个文本文件。

文件名:TextFile.txt

设置为嵌入资源。

"Local File" 有效代码:

string[] spaces = File.ReadAllLines("C:\Users\a\source\repos\a\bin\Debug\TextFile.txt");

当前代码:

        var assembly = Assembly.GetExecutingAssembly();
        var resourceName = "TextFile.txt";

        using (Stream stream = assembly.GetManifestResourceStream(resourceName))
        using (StreamReader reader = new StreamReader(stream))
        {
            string result = reader.ReadToEnd(); 
        }

        string[] spaces = File.ReadAllLines(resourceName);

但我收到以下错误:

System.ArgumentNullException: 'Value cannot be null. Parameter name: stream'

这一行:

using (StreamReader reader = new StreamReader(stream))

EDIT1 按照 link 进行了尝试(Why does GetManifestResourceStream returns null while the resource name exists when calling GetManifestResourceNames?) and this NULL ERROR:

        var assembly = Assembly.GetExecutingAssembly();
        var resourceName = "programname.TextFile.txt";

        using (Stream stream = assembly.GetManifestResourceStream(resourceName))
        using (StreamReader reader = new StreamReader(stream))
        {
            string result = reader.ReadToEnd(); 
        }

        string[] spaces = File.ReadAllLines(resourceName);

同样的错误,我是不是把命名空间位放错地方了?

编辑 2,试过这个:

        var assembly = Assembly.GetExecutingAssembly();
        var resourceName = "programname.Resources.TextFile.txt";
        using (Stream stream = assembly.GetManifestResourceStream(resourceName))
        using (StreamReader reader = new StreamReader(stream))
        {
            string result = reader.ReadToEnd(); 
        }

        string[] spaces = File.ReadAllLines(resourceName);

新错误:

System.IO.FileNotFoundException: 'Could not find file 'C:\Users\a\source\repos\a\bin\Debug\programname.Resources.TextFile.txt'.'

TextFile.txt

的位置
programname
    Resources
        TextFile.txt 

此函数将为您的文件 return 正确的资源名称:

string resourceName = assembly.GetManifestResourceNames()
  .Single(str => str.EndsWith("TextFile.txt"));

第二期:

对于string[] spaces = File.ReadAllLines(resourceName); 您不能使用相同的资源名称(嵌入式资源)。如果您需要逐行阅读文本,请使用例如:

using (StreamReader reader = new StreamReader(stream))
{
   while (reader.Peek() >= 0)
   {
      Console.WriteLine(reader.ReadLine());
   }
}

通过打开 Resources.resx、将 Access Modifier 设置为 Public 然后在其中添加文件来实现。

然后替换为:

string[] spaces = File.ReadAllLines("C:\Users\a\source\repos\a\bin\Debug\TextFile.txt")

有:

var resourceText = Properties.Resources.TextFile;
var Lines= resourceText.Replace("\r", "").Split('\n');

一点背景知识:

MSDN:

If you add a resource to your project in the normal way, it will automatically provide a typesafe wrapper for that resource.

For example, in the Solution Explorer, expand the "Properties" node and double click the "Resources.resx" entry. Then add an image via the "Add Resource" button. Give that resource a name, say "MyImage".

You will then be able to programmatically access that image via "Properties.Resources.MyImage"

  • 这是最简单的推荐方式;它会让您编辑资源文件中的名称,并在编码时检查名称是否正确。

请注意,名称已去除扩展名,并且与其他 c# 名称一样,区分大小写!

  • 另一种方式不使用 .resx 文件注册资源,而仅将它们添加到资源文件夹并将它们标记为嵌入。

要使用它们,您不能使用像上面那样简单的代码。相反,您需要找出名称(Intellisense 不会在那里帮助您)并且它们使用对 Reflection 命名空间的调用。

请注意,这里的名称 __not_- 去掉了扩展名 ,但仍然 区分大小写!

示例:

如果我们不知道确切的名称,我们可以在程序集中搜索:

var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var ress = assembly.GetManifestResourceNames()
                   .Where(x => x.Contains(somepattern)).First();

通常第一种方式比较推荐。仅类型安全和 Intellisense 支持就非常值得维护 resx 文件! 现在我们可以打开一个流来读取资源:

List<string> results = new List<string>(); ;
using (Stream stream = assembly.GetManifestResourceStream(ress))
using (StreamReader reader = new StreamReader(stream))
{
    while (reader.Peek()>=0) results.Add(reader.ReadLine());
}