【问题标题】:Copying embedded resource as file to disk in C#在 C# 中将嵌入资源作为文件复制到磁盘
【发布时间】:2011-05-23 07:00:54
【问题描述】:

我有一个 INF 文件保存为我的 C# 项目中的嵌入式资源。我正在尝试根据需要将此文件保存到本地位置。我正在使用这种方法。

public static void SaveResourceToDisk(string ResourceName, string FileToExtractTo)
{
    Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(ResourceName);
    FileStream resourceFile = new FileStream(FileToExtractTo, FileMode.Create);

    byte[] b = new byte[s.Length + 1];
    s.Read(b, 0, Convert.ToInt32(s.Length));
    resourceFile.Write(b, 0, Convert.ToInt32(b.Length - 1));
    resourceFile.Flush();
    resourceFile.Close();

    resourceFile = null;
}

当我尝试调用此方法(将资源名称与命名空间名称一起传递)时,出现错误:

对象引用未设置为对象的实例

我在这里做错了什么?

【问题讨论】:

  • 如果您发布了完整的错误(包括行号,与代码中的行号匹配),它可能有助于诊断问题。
  • 小贴士:考虑在对象中使用“using”关键字来自动处理它们。
  • 复制stackoverflow.com/questions/864140/…,其中有一个更有用的代码示例。

标签: c# embedded-resource


【解决方案1】:

你可以打电话

System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();

并检查哪些嵌入式资源是可访问的。然后您可以将其与您传入的内容进行比较,看看您是否确实完成了您的预期。

此外,您应该考虑使用 using 关键字来处理您的流:

using(FileStream ResourceFile = new FileStream(FileToExtractTo, FileMode.Create))
{
    //do stuff
}

祝你好运。

【讨论】:

  • 好的,知道了。当我应该使用GetManifestResourceStream(namespace.Resources.resourcename) 时,我正在使用GetManifestResourceStream(namespace.resourcename)。感谢using 的提示!
【解决方案2】:

这是保存嵌入资源的最简单方法:

  var stream = assembly.GetManifestResourceStream("name of the manifest resourse");
  var fileStream = File.Create(@"C:\Test.xml");
  stream.Seek(0, SeekOrigin.Begin);
  stream.CopyTo(fileStream);
  fileStream.Close();

【讨论】:

    【解决方案3】:

    解包程序集中的所有嵌入资源,并将它们与包含此类的程序集一起保存,同时保持目录结构。此代码不需要您了解程序集中包含的文件的任何信息,是一种更通用的解决方案,但它确实假定所有文件都有文件扩展名。

    public class EmbeddedResources
    {
        private bool isUnpacked = false;
    
        public async Task EnsureUnpacked(string saveDirectory)
        {
            if (!this.isUnpacked)
            {
                var assembly = Assembly.GetExecutingAssembly();
                var assemblyDirectory = Path.GetDirectoryName(assembly.Location);
                foreach (var name in assembly.GetManifestResourceNames())
                {
                    var stream = assembly.GetManifestResourceStream(name);
    
                    var stringBuilder = new StringBuilder();
                    var parts = name
                        .Replace(typeof(EmbeddedResources).Namespace + ".", string.Empty)
                        .Split('.')
                        .ToList();
                    for (int i = 0; i < parts.Count; ++i)
                    {
                        var part = parts[i];
                        if (string.Equals(part, string.Empty))
                        {
                            stringBuilder.Append(".");      // Append '.' in file name.
                        }
                        else if (i == parts.Count - 2)
                        {
                            stringBuilder.Append(part);     // Append file name and '.'.
                            stringBuilder.Append('.');
                        }
                        else if (i == parts.Count - 1)
                        {
                            stringBuilder.Append(part);     // Append file extension.
                        }
                        else
                        {
                            stringBuilder.Append(part);     // Append file path.
                            stringBuilder.Append('\\');
                        }
                    }
    
                    var filePath = Path.Combine(saveDirectory, stringBuilder.ToString());
                    using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                    {
                        await stream.CopyToAsync(fileStream);
                    }
                }
    
                this.isUnpacked = true;
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      将您的文件附加到您的项目中。单击附加文件。转到属性,将构建操作设置为嵌入式资源,在代码中使用文件名,如下所示:“YourProjectName.YourFileNameIWithExt”

      【讨论】:

        【解决方案5】:

        我在Resources 中添加了一个 Excel 文件,但使用其他解决方案时运气不佳。这是因为文件本身是通过Properties.Resources 作为byte[] 访问的,而不是选择字符串路径路由。

        所以我只是向用户询问保存路径,然后我使用System.IO.File.WriteAllBytes method:

        using (var save = new SaveFileDialog())
        {
            save.Title = "File path for saving the file";
            save.FileName = "Excel file.xlsx";
            save.Filter = "Excel files|*.xlsx;*.xls";
            var dialog = save.ShowDialog();
            if (dialog != DialogResult.OK)
                return;
        
            System.IO.File.WriteAllBytes(save.FileName, Resources.ExcelFile);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-10-26
          • 1970-01-01
          • 2012-10-13
          • 2013-03-06
          • 1970-01-01
          • 1970-01-01
          • 2022-01-20
          • 1970-01-01
          相关资源
          最近更新 更多