2016-09-06 13 views
0

ConnectStreamでPDFを返すWebAPIを呼び出しています。私はConnectStreamをファイルに書き込んだ後、それをmemorystreamに読み込み、それを電子メールに添付することができます。 IOオーバーヘッドなしで同じことを達成するにはどうすればよいですか?PDFをConnectStreamから電子メールに添付する方法

System.Net.HttpWebResponse webResponse = (System.Net.HttpWebResponse)webRequest.GetResponse(); 

System.IO.Stream stream = webResponse.GetResponseStream(); 

System.IO.StreamReader reader = new System.IO.StreamReader(stream, Encoding.Default); 

string finalPath = System.IO.Path.Combine(outputPath, $"{startDate:yyyy-MM-dd}_{endDate:yyyy-MM-dd}.pdf"); 
System.IO.Stream fileStream = System.IO.File.OpenWrite(finalPath); 

using (System.IO.StreamWriter sw = new System.IO.StreamWriter(fileStream, Encoding.Default)) 
{ 
    sw.Write(reader.ReadToEnd()); 
    sw.Flush(); 
    sw.Close(); 
} 

using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(finalPath))) 
{ 
    using (MailMessage mailMessage = new MailMessage()) 
    { 
     mailMessage.From = new MailAddress("[email protected]"); 

     mailMessage.To.Add("[email protected]"); 

     mailMessage.Attachments.Add(new Attachment(ms, new System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Application.Pdf))); 
     SmtpClient smtpClient = new SmtpClient() { DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.SpecifiedPickupDirectory, PickupDirectoryLocation = outputPath }; 
     smtpClient.Send(mailMessage); 
    } 
} 

答えて

1

まず、要求ストリーム一方向のみのストリームを読み取られ、あなたが操作することができるものにそれを読む必要があるので、ストリームを許可するほとんどのメソッドに渡すことはできません。

public byte[] ReadStreamBinary(Stream stream, int bufferSize) 
    { 
     using (var ms = new MemoryStream()) 
     { 
      var buffer = CreateBuffer(bufferSize); 
      var finished = false; 
      while (!finished) 
      { 
       buffer.Initialize(); 
       var bytes = stream.Read(buffer, 0, buffer.Length); 
       if (bytes > 0) 
       { 
        ms.Write(buffer, 0, bytes); 
       } 
       else 
       { 
        finished = true; 
       } 
      } 
      return ms.ToArray(); 
     } 
    } 

次に、このバイト配列からMemoryStreamを作成するだけです。

ストリームのデフォルトの内部バッファーは4kなので、私はほとんど常にバッファーサイズ(4096)として使用します。あなたの場合、MemoryStreamを直接返すようにメソッドを変更するほうが簡単かもしれません。

ストリームを返すことにした場合は、使用を削除する必要があります(ストリームが閉じられたり破棄されないように)、ストリームポインタを先頭に戻します。

public MemoryStream ReadStreamBinary(Stream stream, int bufferSize) 
    { 
     var ms = new MemoryStream(); 
     var buffer = CreateBuffer(bufferSize); 
     var finished = false; 
     while (!finished) 
     { 
      buffer.Initialize(); 
      var bytes = stream.Read(buffer, 0, buffer.Length); 
      if (bytes > 0) 
      { 
       ms.Write(buffer, 0, bytes); 
      } 
      else 
      { 
       finished = true; 
      } 
     } 

     ms.Seek(0, SeekOrigin.Begin); 
     return ms; 
    } 

呼び出しメソッドでストリームをクローズ/破棄してください。

CreateBufferコードを含めるのを忘れていました。クラスのどこにでも入れてください:

public static Func<int, byte[]> CreateBuffer = x => (byte[])Array.CreateInstance(typeof(byte), x); 
+0

ありがとう! CopyToメソッドを使用してストリームをMemoryStreamにコピーできないのはなぜですか? –

関連する問題