从资源写入文件,其中资源可以是文本或图像
本文关键字:资源 文本 图像 文件 | 更新日期: 2023-09-27 18:31:49
我在尝试将资源文件写入磁盘时遇到问题(所有资源文件都属于同一项目和程序集)。
如果我添加
var temp = Assembly.GetExecutingAssembly().GetManifestResourceNames();
这将返回以下格式的string[]
Gener.OptionsDialogForm.resources
Gener.ProgressDialog.resources
Gener.Properties.Resources.resources
Gener.g.resources
Gener.Resources.reusable.css
Gener.Resources.other.jpg
数组的最后 2 个是我想要的唯一 2 个文件,但我认为这并不能保证这种情况总是如此。随着代码的更改,数组可能会以另一种顺序出现,因此我无法在给定索引处显式调用该项目(temp[4]
)
所以,我可以做
foreach (string item in Assembly
.GetExecutingAssembly()
.GetManifestResourceNames())
{
if (!item.Contains("Gener.Resources."))
continue;
//Do whatever I need to do
}
但这太可怕了!这种方法我面临另一个问题;这不会返回带有扩展名的文件名,只返回Name
,因此,我不知道扩展名是什么。
这是当前的代码
public void CopyAllFiles()
{
var files = Resources.ResourceManager.GetResourceSet(System.Globalization.CultureInfo.CurrentUICulture, true, true);
//var temp = Assembly.GetExecutingAssembly().GetManifestResourceNames();
foreach (DictionaryEntry item in files)
{
using (var resourceFileStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Gener.Resources." + item.Key.ToString() + ".css")) // this won't work, I can't hard code .css as the extension could be different
{
Stream stream = new FileStream(this.DirPath, FileMode.Create, FileAccess.Write);
resourceFileStream.CopyTo(stream);
stream.Dispose();
}
}
files.Dispose();
}
但这似乎...错。。。这是其他人会这样做的方式吗,我确定我错过了一些东西,这样的任务很常见,有更好的解决方案?
资源名称是可预测的,您可以将名称传递给Assembly.GetManifestResourceStream()方法。
更高效的是,Visual Studio为此支持设计器,因此您不必猜测需要传递的字符串。 使用"项目 + 属性"、"资源"选项卡。 单击"添加资源"按钮的下拉箭头,然后选择您的文件。 现在,可以使用变量名称引用代码中的资源。 喜欢:
File.WriteAllText(path, Properties.Resources.reusable);
请考虑在运行时将资源复制到文件的马马虎虎的智慧。 只需使用安装程序或XCopy即可获得完全相同的结果,只需复制一次文件即可。 显着的优点是这些资源不会再占用内存地址空间,并且当您没有对目录的写入权限时,您不会遇到麻烦。 这在启用 UAC 时很常见。
这就是我使用的!希望它能帮助其他人。感觉有些黑客,但它有效!
/// <summary>
/// Copies all the files from the Resource Manifest to the relevant folders.
/// </summary>
internal void CopyAllFiles()
{
var resourceFiles = Assembly.GetExecutingAssembly().GetManifestResourceNames();
foreach (var item in resourceFiles)
{
string basePath = Resources.ResourceManager.BaseName.Replace("Properties.", "");
if (!item.Contains(basePath))
continue;
var destination = this._rootFolder + "''" + this._javaScriptFolder + "''" + item.Replace(basePath + ".", "");
using (Stream resouceFile = Assembly.GetExecutingAssembly().GetManifestResourceStream(item))
using (Stream output = File.Create(destination))
{
resouceFile.CopyTo(output);
}
}
}