2

我有一个 System.Net.Mail.Attachment 对象,其中包含一些 .csv 数据。我需要将附件的内容保存在一个文件中。我试过这个:

        var sb = new StringBuilder();
        sb.AppendLine("Accounts,JOB,Usage Count");


            sb.AppendLine("One,Two,Three");
            sb.AppendLine("One,Two,Three");
            sb.AppendLine("One,Two,Three");

        var stream = new MemoryStream(Encoding.ASCII.GetBytes(sb.ToString()));
        //Add a new attachment to the E-mail message, using the correct MIME type
        var attachment = new Attachment(stream, new ContentType("text/csv"))
        {
            Name = "theAttachment.csv"
        };


            var sr = new StreamWriter(@"C:\Blah\Look.csv");
            sr.WriteLine(attachment.ContentStream.ToString());
            sr.Close();

但该文件只有以下内容:“System.IO.MemoryStream”。你能告诉我如何在那里获得真实数据吗?

谢谢。

4

2 回答 2

6

您不能调用ToString任意流。相反,您应该使用CopyTo

using (var fs = new FileStream(@"C:\temp\Look.csv", FileMode.Create))
{
    attachment.ContentStream.CopyTo(fs);
}

使用它来替换示例的最后三行。默认情况下,ToString只返回该类型的名称,除非该类覆盖 ToString。ContentStream 只是抽象 Stream (在运行时它是 a MemoryStream),所以只有默认实现。

CopyTo是 .NET Framework 4 中的新功能。如果您不使用 .NET Framework 4,则可以使用扩展方法来模仿它:

public static void CopyTo(this Stream fromStream, Stream toStream)
{
    if (fromStream == null)
        throw new ArgumentNullException("fromStream");
    if (toStream == null)
        throw new ArgumentNullException("toStream");

    var bytes = new byte[8092];
    int dataRead;
    while ((dataRead = fromStream.Read(bytes, 0, bytes.Length)) > 0)
        toStream.Write(bytes, 0, dataRead);
}

感谢 Gunnar Peipman 在他的博客上的扩展方法。

于 2013-10-14T12:47:36.210 回答
0

假设您的流不是太大,您可以将其全部写入文件,如下所示:

StreamWriter writer = new StreamWriter(@"C:\Blah\Look.csv"); 
StreamReader reader = new StreamReader(attachment.ContentStream); 
writer.WriteLine(reader.ReadToEnd()); 
writer.Close();

如果它更大,您可能希望将读取分成一个循环,以免破坏您的 RAM(并冒着内存不足异常的风险)。

于 2013-10-14T13:02:40.750 回答