Without a good, minimal, complete代码示例 https://stackoverflow.com/help/mcve无法提供具体建议。
然而,基本问题是:当您将文件作为资源嵌入时,它就不再是文件了。也就是说,原始文件仍然存在,但资源本身无论如何都不是文件。它作为某种特定类型的数据存储在程序集中;从文件源嵌入的资源通常最终作为二进制数据对象。
如何使用这些数据取决于您所说的“嵌入”的含义。在 C# 程序中存储资源实际上有两种常见方法:您可以在项目中使用“Resources”对象,该对象通过项目的...Properties.Resources
类(它又使用ResourceManager
.NET 中的类)。或者您可以简单地将文件添加到项目本身,然后选择“嵌入式资源”构建选项。
如果您使用“资源”设计器,则可以通过多种不同的方式添加文件。一种是使用“新文本文件...”选项,它允许您将新文本复制/粘贴或输入到资源中。这在代码中公开为string
财产在Properties.Resources
目的。如果使用“现有文件...”选项添加资源并选择 Visual Studio 识别为文本文件的文件,也会发生同样的情况。
否则,该文件将作为byte[]
中的属性暴露的对象Properties.Resources
class.
如果您使用“嵌入式资源”构建选项而不是“资源”设计器,则您的数据将通过调用可用Assembly.GetManifestResourceStream(string)
方法,它返回一个Stream
目的。这可以包裹在StreamReader
允许逐行读取它。
直接替换File.ReadAllLines(string)
方法如下所示……
使用“嵌入式资源”:
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
:
使用时您可以执行类似的操作Properties.Resources
班级。它看起来几乎相同:
string[] ReadAllResourceLines(string resourceText)
{
using (StringReader reader = new StringReader(resourceText))
{
return EnumerateLines(reader).ToArray();
}
}
称为像string[] allLines = ReadAllResourceLines(Properties.Resources.MyTextFile);
, where MyTextFile
是您在设计器中添加的资源的属性名称(即string
您传入的第二个示例是文件本身的文本,而不是资源的名称)。
如果您添加了 Visual Studio 无法识别为文本文件的现有文件,则属性类型将为byte[]
代替string
你还需要另一种稍微不同的方法:
string[] ReadAllResourceLines(byte[] resourceData)
{
using (Stream stream = new MemoryStream(resourceData))
using (StreamReader reader = new StreamReader(stream))
{
return EnumerateLines(reader).ToArray();
}
}
请注意,在所有三个示例中,关键是数据最终包装在TextReader
实现,然后用于单独读取每一行,以填充数组。这些都使用相同的EnumerateLines()
我上面展示的辅助方法。
当然,现在您已经了解了如何检索数据,您可以对其进行调整,以便以各种其他方式使用数据,例如,如果您并不真正想要或不需要表示为数组的文本string
对象。