C# 将文件从程序集资源流写入磁盘
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/864140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Write file from assembly resource stream to disk
提问by user7116
I can't seem to find a more efficient way to "copy" an embedded resource to disk, than the following:
我似乎找不到比以下更有效的方法将嵌入式资源“复制”到磁盘:
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;
}
}
}
There appears to be no more direct way to do the copy, unless I'm missing something...
似乎没有更直接的方法来进行复制,除非我遗漏了什么......
采纳答案by Jon Skeet
I'm not sure why you're using BinaryReader
/BinaryWriter
at all. Personally I'd start off with a useful utility method:
我不知道你为什么要使用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);
}
}
then call it:
然后调用它:
using (Stream input = assembly.GetManifestResourceStream(resourceName))
using (Stream output = File.Create(path))
{
CopyStream(input, output);
}
You can change the buffer size of course, or have it as a parameter to the method - but the main point is that this is simplercode. Is it more efficient? Nope. Are you sure you really needthis code to be more efficient? Do you actually have hundreds of megabytes you need to write out to disk?
您当然可以更改缓冲区大小,或者将其作为方法的参数 - 但重点是这是更简单的代码。它更有效率吗?不。你确定你真的需要这个代码来提高效率吗?您实际上是否需要将数百兆字节写入磁盘?
I find I rarely need code to be ultra-efficient, but I almost always need it to be simple. The sort of difference in performance that you might see between this and a "clever" approach (if one is even available) isn't likely to be a complexity-changing effect (e.g. O(n) to O(log n)) - and that'sthe type of performance gain which really can be worth chasing.
我发现我很少需要超级高效的代码,但我几乎总是需要它是简单的。您可能会看到这种与“聪明”方法(如果有的话)之间的性能差异不太可能是复杂性改变的效果(例如 O(n) 到 O(log n))-而这其中真正可以值得追逐的性能增益的类型。
EDIT: As noted in comments, .NET 4.0 has Stream.CopyTo
so you don't need to code this up yourself.
编辑:如评论中所述,.NET 4.0 具有,Stream.CopyTo
因此您无需自己编写代码。
回答by Lloyd
Personally I would do it this way:
我个人会这样做:
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();
}
}
回答by Henk Holterman
You will have to write a loop, if that's your question. But you could do without the reader and writer since the basic Stream already deals with byte[] data.
如果这是你的问题,你将不得不写一个循环。但是你可以不用读写器,因为基本的 Stream 已经处理了 byte[] 数据。
This is about as compact as I can get:
这是我能得到的最紧凑的:
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);
}
}
回答by KoalaBear
If the resource (file) is binary.
如果资源(文件)是二进制的。
File.WriteAllBytes("C:\ResourceName", Resources.ResourceName);
And if the resource (file) is text.
如果资源(文件)是文本。
File.WriteAllText("C:\ResourceName", Resources.ResourceName);
回答by cjbarth
I actually ended up using this single line:
Assembly.GetExecutingAssembly().GetManifestResourceStream("[Project].[File]").CopyTo(New FileStream(FileLocation, FileMode.Create))
. Of course, this is for .Net 4.0
我实际上最终使用了这一行:
Assembly.GetExecutingAssembly().GetManifestResourceStream("[Project].[File]").CopyTo(New FileStream(FileLocation, FileMode.Create))
. 当然,这是针对 .Net 4.0
Update: I found that the line above might keep a file locked such that SQLite reports that the database is read-only. Therefore I ended up with the following:
更新:我发现上面的行可能会锁定一个文件,以便 SQLite 报告数据库是只读的。因此,我最终得到了以下结果:
Using newFile As Stream = New FileStream(FileLocation, FileMode.Create)
Assembly.GetExecutingAssembly().GetManifestResourceStream("[Project].[File]").CopyTo(newFile)
End Using
回答by arcalo
This Worked for me:
这对我有用:
using (MemoryStream input = new MemoryStream(Properties.Resources.*RESOURCE_NAME*))
using (Stream output = File.Create(databasePath)){
input.CopyTo(output)
}