我似乎无法找到一种更有效的方法将嵌入式资源"复制"到磁盘,而不是以下方法:
using (BinaryReader reader = new BinaryReader(
assembly.GetManifestResourceStream(@"Namespace.Resources.File.ext")))
{
using (BinaryWriter writer
= new BinaryWriter(new FileStream(path, FileMode.Create)))
{
long bytesLeft = reader.BaseStream.Length;
while (bytesLeft > 0)
{
// 65535L is < Int32.MaxValue, so no need to test for overflow
byte[] chunk = reader.ReadBytes((int)Math.Min(bytesLeft, 65536L));
writer.Write(chunk);
bytesLeft -= chunk.Length;
}
}
}
Run Code Online (Sandbox Code Playgroud)
似乎没有更直接的方式来复制,除非我遗漏了一些东西......
Jon*_*eet 66
我不确定你为什么要使用BinaryReader/ BinaryWriter.就个人而言,我从一个有用的实用方法开始:
public static void CopyStream(Stream input, Stream output)
{
// Insert null checking here for production
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
}
Run Code Online (Sandbox Code Playgroud)
然后叫它:
using (Stream input = assembly.GetManifestResourceStream(resourceName))
using (Stream output = File.Create(path))
{
CopyStream(input, output);
}
Run Code Online (Sandbox Code Playgroud)
您可以更改缓冲区大小,或者将其作为方法的参数 - 但重点是这是更简单的代码.它效率更高吗?不.您确定您确实需要此代码更高效吗?你真的有数百兆字节要写到磁盘吗?
我发现我很少需要代码来实现超高效,但我几乎总是需要简单.您可能会在"智能"方法(如果有一种方法可用)之间看到的性能差异不太可能是复杂性变化的影响(例如O(n)到O(log n)) - 而这就是性能增益这确实可以值得追逐的类型.
编辑:正如评论中所述,.NET 4.0已经Stream.CopyTo让您无需自己编写代码.
Koa*_*ear 61
如果资源(文件)是二进制的.
File.WriteAllBytes("C:\ResourceName", Resources.ResourceName);
Run Code Online (Sandbox Code Playgroud)
如果资源(文件)是文本.
File.WriteAllText("C:\ResourceName", Resources.ResourceName);
Run Code Online (Sandbox Code Playgroud)
cjb*_*rth 18
我实际上最终使用了这一行:
Assembly.GetExecutingAssembly().GetManifestResourceStream("[Project].[File]").CopyTo(New FileStream(FileLocation, FileMode.Create)).当然,这是针对.Net 4.0的
更新:我发现上面的行可能会锁定文件,以便SQLite报告数据库是只读的.因此我最终得到以下结果:
Using newFile As Stream = New FileStream(FileLocation, FileMode.Create)
Assembly.GetExecutingAssembly().GetManifestResourceStream("[Project].[File]").CopyTo(newFile)
End Using
Run Code Online (Sandbox Code Playgroud)