文件批量下载

来源:互联网 发布:sql注入 from 编辑:程序博客网 时间:2024/05/01 14:41

这两天在公司做的一个需求,由于是新手做任务,所以花了一点时间。


这里简要说明一下需求需要处理的步骤:1、前台页面选择需要批量下载的文件;2、点击“一键下载”按钮,执行一键下载;3、如果选择了多个文件,保存到本地文件之后应该是一个压缩包。

思路:1、前台选择文件时要能得到文件在服务器上的地址;2、点击“一键下载“之后,应该将这些地址传到后台;3、打包。这是难点,不过现在一般都有sharpziplib可以使用,但是要考虑大文件下载的问题。如果只是几个小文件下载的话可以直接在内存中打包,但是如果是大文件就不能这么做了,这时就需要在物理硬盘上打包,并且如果文件过大,打包的时间也会有点稍长,这对用户体验是很不好的,如果想最速度地打包成功,那就setlever为0吧,sharpziplib封装了这个类。dll下载官网是http://www.icsharpcode.net/OpenSource/SharpZipLib/Download.aspx

下面看代码

    ''' <summary>    ''' 批量下载函数    ''' </summary>    ''' <param name="ArrFileName">文件路径</param>    ''' <param name="strDocName">文件名</param>    ''' <param name="context"></param>    ''' <remarks>2014/03/12工作流批量下载增加此函数</remarks>    Private Sub PLDownLoad(ByVal ArrFilePath() As String, ByVal context As System.Web.HttpContext)        '将服务器端文件的相对路径转换为绝对路径        For i As Integer = 0 To ArrFilePath.Length - 1            ArrFilePath(i) = context.Server.MapPath(ArrFilePath(i))        Next        HttpContext.Current.Response.ContentType = "application/octet-stream"        HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;   filename=" + Date.Now.ToString() + ".zip")        '在TempFile文件夹下新建一个.zip的临时文件        Dim tempFileName As String = context.Server.MapPath("/TempFiles") + "\\" + Guid.NewGuid().ToString() + ".zip"        Dim fs As FileStream = New FileStream(tempFileName, FileMode.Create)        fs.Close()        '将要批量下载的文件压缩到临时文件目录,为避免压缩浪费效率,设置压缩比为0        Dim tempFileStream As FileStream = New FileStream(tempFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read)        Dim zos As ZipOutputStream = New ZipOutputStream(tempFileStream)        zos.SetLevel(0)        '获取web.config中配置的分段下载下限        Dim splitDownloadSizeConfig As String = System.Configuration.ConfigurationSettings.AppSettings("SplitDownloadSize")        Dim splitDownloadSize As Long = If(String.IsNullOrEmpty(splitDownloadSizeConfig), 40960 * 1024, CInt(splitDownloadSizeConfig) * 1024)        '要压缩的文件总大小        Dim totalFileSize As Long = 0        '读取需要批量压缩的文件        For Each itemPath As String In ArrFilePath            If File.Exists(itemPath) Then                '获取单个文件实际大小                Dim fileSize As Long = 0                Dim response As FileWebResponse                Try                    response = HttpWebRequest.Create(itemPath).GetResponse()                    fileSize = response.ContentLength                Catch ex As Exception                    MyDB.LogException(ex)                Finally                    If response IsNot Nothing Then                        response.Close()                    End If                End Try                totalFileSize += fileSize                '压缩                Dim fileInfo As FileInfo = New FileInfo(itemPath)                Dim stream As FileStream = New FileStream(itemPath, FileMode.Open, FileAccess.Read, FileShare.Read)                Dim buffer() As Byte = New [Byte](fileSize) {}                Dim length As Integer = stream.Read(buffer, 0, fileSize)                Dim entry As ZipEntry = New ZipEntry(fileInfo.Name)                zos.PutNextEntry(entry)                zos.Write(buffer, 0, length)                stream.Close()            End If        Next        zos.Finish()        zos.Close()        If totalFileSize < splitDownloadSize Then    '文件实际大小小于分段下载下限直接下载            context.Response.WriteFile(tempFileName)            context.Response.End()        Else    '文件实际大小大于等于分段下载下限分段下载            Dim stream As Stream = Nothing            Dim buffer As Byte() = New [Byte](10000) {}            Dim length As Integer            Dim dataToRead As Long            Try                stream = New FileStream(tempFileName, FileMode.Open, FileAccess.Read, FileShare.Read)                dataToRead = stream.Length                While dataToRead > 0                    If context.Response.IsClientConnected Then                        '分段下载                        length = stream.Read(buffer, 0, 10000)                        context.Response.OutputStream.Write(buffer, 0, length)                        context.Response.Flush()                        buffer = New [Byte](10000) {}                        dataToRead = dataToRead - length                    Else                        '客户端在没有下载完前,关闭连接,直接设置为-1,避免死循环                        dataToRead = -1                    End If                End While            Catch ex As Exception                MyDB.LogException(ex)                context.Response.Write("下载过程中发生异常:" & ex.Message)            Finally                If stream IsNot Nothing Then                    stream.Close()                End If            End Try        End If        tempFileStream.Close()                HttpContext.Current.Response.Clear()        HttpContext.Current.Response.End()    End Sub





0 0