我正在调用一个在ConnectStream中返回PDF的WebAPI。我将ConnectStream写入文件,然后将其读回内存流,我可以将其附加到电子邮件中。如果没有IO开销,我怎样才能完成同样的事情?
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("noreply@somedomain.com");
mailMessage.To.Add("someone@somedomain.com");
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);
}
}
答案 0 :(得分: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);