2013-10-14 2 views
2

У меня есть объект System.Net.Mail.Attachment с некоторыми данными .csv в нем. Мне нужно сохранить содержимое вложения в файле. Я попытался это:Как получить содержимое System.Net.Mail.Attachment

 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". Не могли бы вы рассказать мне, как я могу получить реальные данные?

Спасибо.

+0

Использовать записи файлов для записи этого потока в файл? –

+0

Вы не можете вызвать 'ToString' в случайном потоке, который обычно просто печатает имя типа. Для копирования потока в другой поток необходимо использовать «CopyTo». – vcsjones

+0

Если он не слишком большой, вы можете просто вызвать 'ContentStream.ReadToEnd()' –

ответ

0

Предполагая, что ваш поток не слишком большой, вы можете просто написать все это в файл следующим образом:

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

Если это больше вы, вероятно, хотите, чтобы кусок чтений вверх в петлю, чтобы не разрушить ваша оперативная память (и исключение из памяти исключений из памяти).

4

Вы не можете позвонить ToString на произвольный поток. Вместо этого вы должны использовать CopyTo:

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

Используйте это, чтобы заменить последние три строки вашего примера. По умолчанию ToString просто возвращает это имя типа, если класс не переопределяет ToString. ContentStream - это всего лишь абстрактный поток (во время выполнения это 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); 
} 

Кредит на Гуннар Peipman для метода расширения на his blog.

+0

Спасибо, это тоже работает. Это лучше, чем ReadToEnd()? –

+0

@DavidShochet Возможно, возможно нет. Они оба выполняют одно и то же, это будет использовать меньше памяти для очень больших файловых вложений с момента его буферизации. – vcsjones

Смежные вопросы