如何使用StreamReader读取嵌入式资源(文本文件)并将其作为字符串返回?我当前的脚本使用Windows窗体和文本框,允许用户查找和替换未嵌入的文本文件中的文本。

private void button1_Click(object sender, EventArgs e)
{
    StringCollection strValuesToSearch = new StringCollection();
    strValuesToSearch.Add("Apple");
    string stringToReplace;
    stringToReplace = textBox1.Text;

    StreamReader FileReader = new StreamReader(@"C:\MyFile.txt");
    string FileContents;
    FileContents = FileReader.ReadToEnd();
    FileReader.Close();
    foreach (string s in strValuesToSearch)
    {
        if (FileContents.Contains(s))
            FileContents = FileContents.Replace(s, stringToReplace);
    }
    StreamWriter FileWriter = new StreamWriter(@"MyFile.txt");
    FileWriter.Write(FileContents);
    FileWriter.Close();
}

当前回答

可以使用两种不同的方法将文件添加为资源。

访问文件所需的C#代码不同,这取决于首先添加文件所用的方法。

方法1:添加现有文件,将属性设置为Embedded Resource

将文件添加到项目中,然后将类型设置为“嵌入式资源”。

注意:如果使用此方法添加文件,则可以使用GetManifestResourceStream访问它(请参阅@dtb的答案)。

方法2:将文件添加到Resources.resx

打开Resources.resx文件,使用下拉框添加文件,将AccessModifier设置为public。

注意:如果使用此方法添加文件,则可以使用财产.资源访问它(请参阅@Night Walker的回答)。

其他回答

可以使用两种不同的方法将文件添加为资源。

访问文件所需的C#代码不同,这取决于首先添加文件所用的方法。

方法1:添加现有文件,将属性设置为Embedded Resource

将文件添加到项目中,然后将类型设置为“嵌入式资源”。

注意:如果使用此方法添加文件,则可以使用GetManifestResourceStream访问它(请参阅@dtb的答案)。

方法2:将文件添加到Resources.resx

打开Resources.resx文件,使用下拉框添加文件,将AccessModifier设置为public。

注意:如果使用此方法添加文件,则可以使用财产.资源访问它(请参阅@Night Walker的回答)。

我想将嵌入式资源作为字节数组读取(不考虑任何特定编码),最后我使用了MemoryStream,这使得它非常简单:

using var resStream = assembly.GetManifestResourceStream(GetType(), "file.txt");
var ms = new MemoryStream();
await resStream .CopyToAsync(ms);
var bytes = ms.ToArray();

通过您的所有能力,我使用这个助手类以通用方式从任何程序集和任何命名空间读取资源。

public class ResourceReader
{
    public static IEnumerable<string> FindEmbededResources<TAssembly>(Func<string, bool> predicate)
    {
        if (predicate == null) throw new ArgumentNullException(nameof(predicate));

        return
            GetEmbededResourceNames<TAssembly>()
                .Where(predicate)
                .Select(name => ReadEmbededResource(typeof(TAssembly), name))
                .Where(x => !string.IsNullOrEmpty(x));
    }

    public static IEnumerable<string> GetEmbededResourceNames<TAssembly>()
    {
        var assembly = Assembly.GetAssembly(typeof(TAssembly));
        return assembly.GetManifestResourceNames();
    }

    public static string ReadEmbededResource<TAssembly, TNamespace>(string name)
    {
        if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
        return ReadEmbededResource(typeof(TAssembly), typeof(TNamespace), name);
    }

    public static string ReadEmbededResource(Type assemblyType, Type namespaceType, string name)
    {
        if (assemblyType == null) throw new ArgumentNullException(nameof(assemblyType));
        if (namespaceType == null) throw new ArgumentNullException(nameof(namespaceType));
        if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));

        return ReadEmbededResource(assemblyType, $"{namespaceType.Namespace}.{name}");
    }

    public static string ReadEmbededResource(Type assemblyType, string name)
    {
        if (assemblyType == null) throw new ArgumentNullException(nameof(assemblyType));
        if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));

        var assembly = Assembly.GetAssembly(assemblyType);
        using (var resourceStream = assembly.GetManifestResourceStream(name))
        {
            if (resourceStream == null) return null;
            using (var streamReader = new StreamReader(resourceStream))
            {
                return streamReader.ReadToEnd();
            }
        }
    }
}

我读取了一个嵌入式资源文本文件,使用:

    /// <summary>
    /// Converts to generic list a byte array
    /// </summary>
    /// <param name="content">byte array (embedded resource)</param>
    /// <returns>generic list of strings</returns>
    private List<string> GetLines(byte[] content)
    {
        string s = Encoding.Default.GetString(content, 0, content.Length - 1);
        return new List<string>(s.Split(new[] { Environment.NewLine }, StringSplitOptions.None));
    }

示例:

var template = GetLines(Properties.Resources.LasTemplate /* resource name */);

template.ForEach(ln =>
{
    Debug.WriteLine(ln);
});

答案很简单,如果直接从resources.resx添加文件,只需这样做。

string textInResourceFile = fileNameSpace.Properties.Resources.fileName;

使用这行代码,文件中的文本将直接从文件中读取并放入字符串变量中。