将程序集资源stream中的文件写入磁盘

我似乎无法find一个更有效的方法来“复制”embedded式资源到磁盘,比以下内容:

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

似乎没有更直接的方式来做副本,除非我失去了一些东西…

我不知道你为什么使用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); } } 

然后调用它:

 using (Stream input = assembly.GetManifestResourceStream(resourceName)) using (Stream output = File.Create(path)) { CopyStream(input, output); } 

当然你可以改变缓冲区的大小,或者把它作为方法的一个参数 – 但最重要的是这是简单的代码。 效率更高吗? 不。 你确定你确实需要这个代码来提高效率吗? 你真的有数百兆字节你需要写出到磁盘?

我发现我很less需要代码来超高效,但我几乎总是需要它是简单的。 你可能会看到这种与“巧妙”的方法(如果有的话)之间的性能差异不太可能是复杂性变化的影响(例如O(n)到O(log n)) – 这就是性能增益的types,这是值得追求的。

编辑:正如在注释中指出的,.NET 4.0有Stream.CopyTo所以你不需要自己编写代码。

如果资源(文件)是二进制的。

 File.WriteAllBytes("C:\ResourceName", Resources.ResourceName); 

如果资源(文件)是文本。

  File.WriteAllText("C:\ResourceName", Resources.ResourceName); 

我实际上结束了使用这一行: Assembly.GetExecutingAssembly().GetManifestResourceStream("[Project].[File]").CopyTo(New FileStream(FileLocation, FileMode.Create)) 。 当然,这是为.NET 4.0

更新:我发现上面的行可能会locking一个文件,SQLite会报告数据库是只读的。 所以我结束了以下几点:

 Using newFile As Stream = New FileStream(FileLocation, FileMode.Create) Assembly.GetExecutingAssembly().GetManifestResourceStream("[Project].[File]").CopyTo(newFile) End Using 

我个人会这样做:

 using (BinaryReader reader = new BinaryReader( assembly.GetManifestResourceStream(@"Namespace.Resources.File.ext"))) { using (BinaryWriter writer = new BinaryWriter(new FileStream(path, FileMode.Create))) { byte[] buffer = new byte[64 * 1024]; int numread = reader.Read(buffer,0,buffer.Length); while (numread > 0) { writer.Write(buffer,0,numread); numread = reader.Read(buffer,0,buffer.Length); } writer.Flush(); } } 

如果这是你的问题,你将不得不写一个循环。 但是由于Stream已经处理了byte []数据,所以你可以不用读写器。

这是关于我可以得到的一样紧凑:

 using (Stream inStream = File.OpenRead(inputFile)) using (Stream outStream = File.OpenWrite(outputFile)) { int read; byte[] buffer = new byte[64 * 1024]; while ((read = inStream.Read(buffer, 0, buffer.Length)) > 0) { outStream.Write(buffer, 0, read); } }