如何将ConnectStream中的PDF附加到电子邮件



我正在调用一个WebAPI,它在ConnectStream中返回PDF。我将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);
    }
}

首先,请求流是单向只读流,不能传递给大多数允许流的方法,因此需要将其读入可以操作的内容:

    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可能更容易。

如果你决定返回流,你需要删除using(这样流就不会被关闭/处理),并返回流指针到开始。

    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);

相关内容

  • 没有找到相关文章

最新更新