如何使用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();
}

当前回答

这是一个类,您可能会发现从当前程序集读取嵌入式资源文件非常方便:

using System.IO;
using System.Linq;
using System.Text;
using System.Reflection;

public static class EmbeddedResourceUtils
{
    public static string ReadFromResourceFile(string endingFileName)
    {
        var assembly = Assembly.GetExecutingAssembly();
        var manifestResourceNames = assembly.GetManifestResourceNames();

        foreach (var resourceName in manifestResourceNames)
        {
            var fileNameFromResourceName = _GetFileNameFromResourceName(resourceName);
            if (!fileNameFromResourceName.EndsWith(endingFileName))
            {
                continue;
            }

            using (var manifestResourceStream = assembly.GetManifestResourceStream(resourceName))
            {
                if (manifestResourceStream == null)
                {
                    continue;
                }

                using (var streamReader = new StreamReader(manifestResourceStream))
                {
                    return streamReader.ReadToEnd();
                }
            }
        }

        return null;
    }
    
    // https://stackoverflow.com/a/32176198/3764804
    private static string _GetFileNameFromResourceName(string resourceName)
    {
        var stringBuilder = new StringBuilder();
        var escapeDot = false;
        var haveExtension = false;

        for (var resourceNameIndex = resourceName.Length - 1;
            resourceNameIndex >= 0;
            resourceNameIndex--)
        {
            if (resourceName[resourceNameIndex] == '_')
            {
                escapeDot = true;
                continue;
            }

            if (resourceName[resourceNameIndex] == '.')
            {
                if (!escapeDot)
                {
                    if (haveExtension)
                    {
                        stringBuilder.Append('\\');
                        continue;
                    }

                    haveExtension = true;
                }
            }
            else
            {
                escapeDot = false;
            }

            stringBuilder.Append(resourceName[resourceNameIndex]);
        }

        var fileName = Path.GetDirectoryName(stringBuilder.ToString());
        return fileName == null ? null : new string(fileName.Reverse().ToArray());
    }
}

其他回答

public class AssemblyTextFileReader
{
    private readonly Assembly _assembly;

    public AssemblyTextFileReader(Assembly assembly)
    {
        _assembly = assembly ?? throw new ArgumentNullException(nameof(assembly));
    }

    public async Task<string> ReadFileAsync(string fileName)
    {
        var resourceName = _assembly.GetManifestResourceName(fileName);

        using (var stream = _assembly.GetManifestResourceStream(resourceName))
        {
            using (var reader = new StreamReader(stream))
            {
                return await reader.ReadToEndAsync();
            }
        }
    }
}

public static class AssemblyExtensions
{
    public static string GetManifestResourceName(this Assembly assembly, string fileName)
    {
        string name = assembly.GetManifestResourceNames().SingleOrDefault(n => n.EndsWith(fileName, StringComparison.InvariantCultureIgnoreCase));

        if (string.IsNullOrEmpty(name))
        {
            throw new FileNotFoundException($"Embedded file '{fileName}' could not be found in assembly '{assembly.FullName}'.", fileName);
        }

        return name;
    }
}
// To use the code above:
var reader = new AssemblyTextFileReader(assembly);

string text = await reader.ReadFileAsync(@"MyFile.txt");

阅读了这里张贴的所有解决方案后。我就是这样解决的:

// How to embedded a "Text file" inside of a C# project
//   and read it as a resource from c# code:
//
// (1) Add Text File to Project.  example: 'myfile.txt'
//
// (2) Change Text File Properties:
//      Build-action: EmbeddedResource
//      Logical-name: myfile.txt      
//          (note only 1 dot permitted in filename)
//
// (3) from c# get the string for the entire embedded file as follows:
//
//     string myfile = GetEmbeddedResourceFile("myfile.txt");

public static string GetEmbeddedResourceFile(string filename) {
    var a = System.Reflection.Assembly.GetExecutingAssembly();
    using (var s = a.GetManifestResourceStream(filename))
    using (var r = new System.IO.StreamReader(s))
    {
        string result = r.ReadToEnd();
        return result;
    }
    return "";      
}

我知道这是一条古老的线索,但这对我来说是有效的:

将文本文件添加到项目资源将访问修饰符设置为public,如Andrew Hill所示阅读文本如下:textBox1=新文本框();textBox1.Text=属性.Resources.SomeText;

我添加到资源中的文本:“SomeText.txt”

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

    /// <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);
});

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

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();
            }
        }
    }
}