文件通过压缩包下载

做项目的时候需要把一些文件按一定的结构批量下载,这时候使用压缩包下载会更合理一些。

思路是把文件转成 MemoryStream 然后添加到 KeyValuePair 中,再通过压缩包帮助类进行压缩,然后下载

一、文件转字节流

如果是NPOI生成的IWrokBook文件

//生成的目录说明文件
var catalogue = _taskdataAppService.ExportCatalogue(targetAttachment);
//创建新的MemoryStream流
var catalogueStream = new MemoryStream();
//写入到流
catalogue.Write(catalogueStream);

如果是服务器端的文件

// 打开文件
FileStream fileStream = new FileStream(file.Path, FileMode.Open, FileAccess.Read, FileShare.Read);
// 读取文件的 byte[]
byte[] bytes = new byte[fileStream.Length];
fileStream.Read(bytes, 0, bytes.Length);
fileStream.Close();

二、添加到 List<KeyValuePair<byte[], string>>()

新建列表,然后通过foreach将文件添加

files.Add(new KeyValuePair<byte[], string>(bytes, $@"{firstTargetNname}\{secendTargetNname}\{thirdTargetNname}\{file.Name}"));

如果是要添加目录在filename前加 “ \ ” 就行,如果创建没有文件的空文件夹,则需要添加一个字符串列表

path.Add($@"{firstTargetNname}\{secendTargetNname}\{thirdTargetNname}");

三、调用帮助类

用的是 SharpZipLib 

  /// <summary>
    /// 文件转压缩包对象
    /// </summary>
    public class FilesToZipByteExtension
    {
        /// <summary>
        /// 文件添加到压缩包
        /// </summary>
        /// <param name="files">KeyValuePair:MemoryStream,FilePath/FileName</param>
        /// <returns></returns>
        public static byte[] FileToZip(List<KeyValuePair<byte[], string>> files)
        {
            MemoryStream zipStream = new MemoryStream();
            using (ZipFile zip = ZipFile.Create(zipStream))
            {
                zip.BeginUpdate();

                foreach (var file in files)
                {
                    StringDataSource d1 = new StringDataSource(file.Key);
                    zip.Add(d1, file.Value);
                }

                zip.CommitUpdate();
                return zipStream.ToArray();
            }
        }

        /// <summary>
        /// 文件添加到压缩包
        /// </summary>
        /// <param name="files">KeyValuePair:MemoryStream,FilePath/FileName</param>
        /// <param name="pathList">FilePath</param>
        /// <returns></returns>
        public static byte[] FileToZip(List<KeyValuePair<byte[], string>> files,List<string> pathList)
        {
            MemoryStream zipStream = new MemoryStream();
            using (ZipFile zip = ZipFile.Create(zipStream))
            {
                zip.BeginUpdate();

                foreach (var path in pathList)
                {
                    zip.AddDirectory(path);
                }
                foreach (var file in files)
                {
                    StringDataSource d1 = new StringDataSource(file.Key);
                    zip.Add(d1, file.Value);
                }

                zip.CommitUpdate();
                return zipStream.ToArray();
            }
        }
    }
    class StringDataSource : IStaticDataSource
    {
        private byte[] Buffer { get; set; }
        public StringDataSource(byte[] buffer)
        {
            Buffer = buffer;
        }
        public Stream GetSource()
        {
            return new MemoryStream(Buffer);
        }
    }
View Code

如果不需要创建空文件夹,可以用第一个方法。

返回的就是压缩包的文件流了,可以通过return File返回给其他调用者。

 

posted @ 2021-06-24 15:29  天辰啦啦啦  阅读(191)  评论(0)    收藏  举报