使用MemoryStream而不是FileStream时,无法保存更改
我有一个嵌入 Excel 文件的 DLL。目标是检索此文件并创建一些条目(本例中为 Empty_File.txt
)。当我使用 FileStream
时,会创建条目,但是当我使用 MemoryStream
时,不会创建条目。
var filePath = "C:\\Temp\\Test2.xlsx";
var asm = typeof(Program).Assembly;
var asmName = asm.GetName().Name;
using var resourceStream = asm.GetManifestResourceStream($"{asmName}.Resources.Template.xlsx");
if (File.Exists(filePath)) File.Delete(filePath);
await UseFileStream(resourceStream, filePath);
// or
await UseMemoryStream(resourceStream, filePath);
static async Task UseMemoryStream(Stream resourceStream, string filePath)
{
using (var ms = new MemoryStream())
{
await resourceStream.CopyToAsync(ms);
using (var zip = new ZipArchive(ms, ZipArchiveMode.Update))
{
zip.CreateEntry("Empty_File.txt");
using (var fs = CreateFileStream(filePath))
{
ms.Seek(0L, SeekOrigin.Begin);
await ms.CopyToAsync(fs);
}
}
}
}
static async Task UseFileStream(Stream resourceStream, string filePath)
{
using var fs = CreateFileStream(filePath);
await resourceStream.CopyToAsync(fs);
using var zip = new ZipArchive(fs, ZipArchiveMode.Update);
zip.CreateEntry("Empty_File.txt");
}
static FileStream CreateFileStream(string filePath) =>
new FileStream(filePath, new FileStreamOptions
{
Access = FileAccess.ReadWrite,
Mode = FileMode.Create,
Share = FileShare.None
});
I have a DLL with embedded Excel file. The goal is to retrieve this file and create some entry (Empty_File.txt
in this example). When I'm using FileStream
- the entry gets created, but when I'm using MemoryStream
- entry isn't created.
var filePath = "C:\\Temp\\Test2.xlsx";
var asm = typeof(Program).Assembly;
var asmName = asm.GetName().Name;
using var resourceStream = asm.GetManifestResourceStream(quot;{asmName}.Resources.Template.xlsx");
if (File.Exists(filePath)) File.Delete(filePath);
await UseFileStream(resourceStream, filePath);
// or
await UseMemoryStream(resourceStream, filePath);
static async Task UseMemoryStream(Stream resourceStream, string filePath)
{
using (var ms = new MemoryStream())
{
await resourceStream.CopyToAsync(ms);
using (var zip = new ZipArchive(ms, ZipArchiveMode.Update))
{
zip.CreateEntry("Empty_File.txt");
using (var fs = CreateFileStream(filePath))
{
ms.Seek(0L, SeekOrigin.Begin);
await ms.CopyToAsync(fs);
}
}
}
}
static async Task UseFileStream(Stream resourceStream, string filePath)
{
using var fs = CreateFileStream(filePath);
await resourceStream.CopyToAsync(fs);
using var zip = new ZipArchive(fs, ZipArchiveMode.Update);
zip.CreateEntry("Empty_File.txt");
}
static FileStream CreateFileStream(string filePath) =>
new FileStream(filePath, new FileStreamOptions
{
Access = FileAccess.ReadWrite,
Mode = FileMode.Create,
Share = FileShare.None
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
per for
ziparchive.dispose
:您当前正在写入File Stream 之前,因此尚未编写zip文件的更改。
您还可以从中注意到,除非您在构造函数中指定
true
,否则将处置基础MemoryStream
,这将阻止您在后面复制到文件。因此,将这两者都放在一起:
Per the docs for
ZipArchive.Dispose
:You are currently writing to the file stream before this happens, so the changes to the zip file haven't been written yet.
You'll also note from this that the underlying
MemoryStream
will be disposed unless you specifyleaveOpen: true
in the constructor, which would prevent you copying to the file afterwards.So putting both of these together: