首页 > 解决方案 > 如何将文件流直接保存到 C# 中的 excel 文件中?

问题描述

为了给您一些背景信息,我尝试在一次批量操作中下载一堆附件。这些附件通常通过网站一次下载一个文件,检索附件的 MVC 控制器代码如下所示:

    var attachment = _attachmentsRepository.GetAttachment(websiteId, id);
    if (attachment.FileStream == null || !attachment.FileStream.CanRead)
    {
        return new HttpResponseMessage(HttpStatusCode.BadRequest);
    }

     var content = new StreamContent(attachment.FileStream);
     content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = $"{id}.{attachment.Extension}" };

     return new HttpResponseMessage(HttpStatusCode.OK) { Content = content };

我想要做的是为批量操作编写一个控制台应用程序,它将每个文件直接保存到磁盘上,到目前为止,我为单个文件保存的内容是:

        var = attachment attachmentsRepository.GetAttachment(websiteId, resource.Id);
        attachment.FileStream.Position = 0;
        var reader = new StreamReader(attachment.FileStream);
        var content = reader.ReadToEnd();
        File.WriteAllText(someFilePath, content);

我已经避开了任何 http 特定的框架类,因为我只需要通过代码而不是浏览器直接下载到文件。此代码成功生成文件,但是当我打开它们时,Excel 表明它们已损坏,我怀疑这是编码问题。我目前正在使用编码,但到目前为止运气并不好,因此不胜感激。

标签: c#stream

解决方案


不要StreamReader用于处理二进制数据。StreamReader/StreamWriter类用于在 a 中读取和写入人类可读的文本,因此Stream它们试图执行可以破坏二进制数据的文本编码/解码(我觉得这些类应该重命名为StreamTextReader/StreamTextWriter以反映它们的继承层次结构)。

要读取原始二进制数据,请Stream直接使用类上的方法(例如ReadWriteCopyTo)。

尝试这个:

var attachment = ...
using( FileStream fs = new FileStream( someFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.None, bufferSize: 8 * 1024, useAsync: true ) )
{
    await attachment.FileStream.CopyToAsync( fs );
}

using()块将确保fs正确刷新和关闭。


推荐阅读