压缩文件并将其附加到MailMessage而不保存文件

时间:2013-11-06 02:48:33

标签: c# .net zip dotnetzip

我正在开发一个小型的C#ASP.NET Web应用程序,它从我的服务器中提取3个文件,创建这些文件的zip文件,并将zip文件发送给电子邮件收件人。

我遇到的问题是找到一种方法来组合这3个文件,而无需在服务器的硬盘上创建zip文件。我想我需要使用某种内存流或文件流,但在将它们合并为1个zip文件时,我有点超出了我的理解。我已经尝试过SharpZipLib和DotNetZip,但我无法弄明白。

我不想在本地保存zip的原因是这个应用程序上可能同时有很多用户,而且我不想用这些拉链阻塞我的服务器机器。我正在寻找2个答案,如何在不将zip文件保存为文件的情况下压缩文件,以及如何将该zip文件附加到MailMessage。

2 个答案:

答案 0 :(得分:0)

检查SharpZipLib的此示例: https://github.com/icsharpcode/SharpZipLib/wiki/Zip-Samples#wiki-anchorMemory

using ICSharpCode.SharpZipLib.Zip;

// Compresses the supplied memory stream, naming it as zipEntryName, into a zip,
// which is returned as a memory stream or a byte array.
//
public MemoryStream CreateToMemoryStream(MemoryStream memStreamIn, string zipEntryName) {

    MemoryStream outputMemStream = new MemoryStream();
    ZipOutputStream zipStream = new ZipOutputStream(outputMemStream);

    zipStream.SetLevel(3); //0-9, 9 being the highest level of compression

    ZipEntry newEntry = new ZipEntry(zipEntryName);
    newEntry.DateTime = DateTime.Now;

    zipStream.PutNextEntry(newEntry);

    StreamUtils.Copy(memStreamIn, zipStream, new byte[4096]);
    zipStream.CloseEntry();

    zipStream.IsStreamOwner = false;    // False stops the Close also Closing the underlying stream.
    zipStream.Close();          // Must finish the ZipOutputStream before using outputMemStream.

    outputMemStream.Position = 0;
    return outputMemStream;

    // Alternative outputs:
    // ToArray is the cleaner and easiest to use correctly with the penalty of duplicating allocated memory.
    byte[] byteArrayOut = outputMemStream.ToArray();

    // GetBuffer returns a raw buffer raw and so you need to account for the true length yourself.
    byte[] byteArrayOut = outputMemStream.GetBuffer();
    long len = outputMemStream.Length;
}

答案 1 :(得分:0)

试试这个:

public static Attachment CreateAttachment(string fileNameAndPath, bool zipIfTooLarge = true, int bytes = 1 << 20)
{
    if (!zipIfTooLarge)
    {
        return new Attachment(fileNameAndPath);
    }

    var fileInfo = new FileInfo(fileNameAndPath);
    // Less than 1Mb just attach as is.
    if (fileInfo.Length < bytes)
    {
        var attachment = new Attachment(fileNameAndPath);

        return attachment;
    }

    byte[] fileBytes = File.ReadAllBytes(fileNameAndPath);

    using (var memoryStream = new MemoryStream())
    {
        string fileName = Path.GetFileName(fileNameAndPath);

        using (var zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create))
        {
            ZipArchiveEntry zipArchiveEntry = zipArchive.CreateEntry(fileName, CompressionLevel.Optimal);

            using (var streamWriter = new StreamWriter(zipArchiveEntry.Open()))
            {
                streamWriter.Write(Encoding.Default.GetString(fileBytes));
            }
        }

        var attachmentStream = new MemoryStream(memoryStream.ToArray());
        string zipname = $"{Path.GetFileNameWithoutExtension(fileName)}.zip";
        var attachment = new Attachment(attachmentStream, zipname, MediaTypeNames.Application.Zip);

        return attachment;
    }
}