WebServices 大文件上传/下载载方案

服务端:

    ''' <summary>
    ''' 接收上传的文件.
    ''' </summary>
    ''' <param name="Int_UserAUID"></param>
    ''' <param name="UserFaithVag"></param>
    ''' <param name="FileName"></param>
    ''' <param name="Overlay"></param>
    ''' <param name="FileByte"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <WebMethod()> _
    Public Function UpdateFile(ByVal FileName As String, _
                               ByVal Overlay As Boolean, _
                               ByVal FileByte As Byte()) As Int32

        Dim SaveFilePath As String = System.Web.Hosting.HostingEnvironment.MapPath("~") & "/UpLoadFiles/" & FileName
        Dim DirPath As String = New IO.FileInfo(SaveFilePath).DirectoryName

        If Not IO.Directory.Exists(DirPath) Then
            IO.Directory.CreateDirectory(DirPath)
        End If

        If IO.File.Exists(SaveFilePath) Then
            If Overlay Then
                IO.File.Delete(SaveFilePath)
            Else
                Return 1 '//文件已存在.
            End If
        End If

        Dim FileStream As System.IO.FileStream = New System.IO.FileStream(SaveFilePath, IO.FileMode.CreateNew)
        Try
            FileStream.Write(FileByte, 0, FileByte.Length)
            FileStream.Close()
            Return 0
        Catch
            FileStream.Close()
            Return 2
        End Try

    End Function


    ''' <summary>
    ''' 将文件返回客户端.
    ''' </summary>
    ''' <param name="Int_UserAUID"></param>
    ''' <param name="UserFaithVag"></param>
    ''' <param name="FileName"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <WebMethod()> _
Public Function LoadFile(ByVal FileName As String) As Byte()


        Dim LoadFilePath As String = System.Web.Hosting.HostingEnvironment.MapPath("~") & "/UpLoadFiles/" & FileName
        Dim FileByte() As Byte

        If IO.File.Exists(LoadFilePath) Then
            Try
                FileByte = IO.File.ReadAllBytes(LoadFilePath)
                Return FileByte
            Catch
                Return Nothing
            End Try
        Else
            Return Nothing
        End If

    End Function

    ''' <summary>
    ''' 客户端分块上传文件
    ''' </summary>
    ''' <param name="Int_UserAUID"></param>
    ''' <param name="UserFaithVag"></param>
    ''' <param name="FileName">文件名</param>
    ''' <param name="Overlay">是否覆盖原文件</param>
    ''' <param name="BlockID">当前上传的块.0开始编号</param>
    ''' <param name="FileByte">块内容</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <WebMethod()> _
Public Function UpdateFileByBlock(ByVal FileName As String, _
                                  ByVal Overlay As Boolean, _
                                  ByVal BlockID As Int32, _
                                  ByVal FileByte As Byte()) As Int32

        Dim SaveFilePath As String = System.Web.Hosting.HostingEnvironment.MapPath("~") & "/UpLoadFiles/" & FileName
        Dim DirPath As String = New IO.FileInfo(SaveFilePath).DirectoryName

        If Not IO.Directory.Exists(DirPath) Then
            IO.Directory.CreateDirectory(DirPath)
        End If

        If BlockID = 0 Then '//收到的第一个块.
            If IO.File.Exists(SaveFilePath) Then
                If Overlay Then
                    IO.File.Delete(SaveFilePath)
                Else
                    Return 1 '//文件已存在.
                End If
            End If
        End If

        Dim FileStream As System.IO.FileStream
        If BlockID = 0 Then
            FileStream = New System.IO.FileStream(SaveFilePath, IO.FileMode.CreateNew)
        Else
            FileStream = New System.IO.FileStream(SaveFilePath, IO.FileMode.Append)
        End If

        Try
            FileStream.Write(FileByte, 0, FileByte.Length)
            FileStream.Close()
            Return 0
        Catch
            FileStream.Close()
            Return 2
        End Try

    End Function

    ''' <summary>
    ''' 客户端分块下载时,取分割的文件块数.
    ''' </summary>
    ''' <param name="Int_UserAUID"></param>
    ''' <param name="UserFaithVag"></param>
    ''' <param name="ServerFileName">服务器端的文件名</param>
    ''' <param name="BlockSize">块大小</param>
    ''' <returns>被分割文件的块数.最小值是1.</returns>
    ''' <remarks></remarks>
    <WebMethod()> _
    Public Function LoadFileSplit(ByVal ServerFileName As String, _
                                  ByVal BlockSize As Int32) As Int32

        Dim SFilePath As String = System.Web.Hosting.HostingEnvironment.MapPath("~") & "/UpLoadFiles/" & ServerFileName
        Dim FileLenth As Long
        Dim BlackMax As Int32
        Dim Succeed As Boolean = True

        If Not IO.File.Exists(SFilePath) Then
            Return 0
        End If

        If BlockSize <= 0 Then BlockSize = 1024 * 1024
        FileLenth = New IO.FileInfo(SFilePath).Length
        BlackMax = FileLenth \ BlockSize + IIf(FileLenth Mod BlockSize > 0, 1, 0)

        Return BlackMax

    End Function

    ''' <summary>
    ''' 客户端大文件的分块传输.
    ''' </summary>
    ''' <param name="Int_UserAUID"></param>
    ''' <param name="UserFaithVag"></param>
    ''' <param name="BlockID">取第几块.编号从 0 开始.</param>
    ''' <param name="ServerFileName"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <WebMethod()> _
     Public Function LoadFileByBlock(ByVal BlockID As Int32, _
                                     ByVal BlockSize As Int32, _
                                     ByVal ServerFileName As String) As Byte()


        Dim LocalFileName As String = System.Web.Hosting.HostingEnvironment.MapPath("~") & "/UpLoadFiles/" & ServerFileName
        Dim FileByte() As Byte
        Dim FileLenth As Long
        Dim Succeed As Boolean = True
        Dim Offset As Int32     '//偏移量
        Dim SpareLenth As Int32 '//剩余长度.
        Dim fs As FileStream = New FileStream(LocalFileName, FileMode.Open)

        If BlockSize <= 0 Then BlockSize = 1024 * 1024
        FileLenth = New IO.FileInfo(LocalFileName).Length
        Offset = BlockID * BlockSize
        SpareLenth = FileLenth - BlockID * BlockSize '//剩余字节数.

        If SpareLenth <= BlockSize Then
            ReDim FileByte(SpareLenth - 1)
            fs.Seek(Offset, SeekOrigin.Begin)
            fs.Read(FileByte, 0, SpareLenth)
        Else
            ReDim FileByte(BlockSize - 1)
            fs.Seek(Offset, SeekOrigin.Begin)
            fs.Read(FileByte, 0, BlockSize)
        End If
        fs.Close()

        Return FileByte

    End Function

    ''' <summary>
    ''' 删除上传目录下的一个文件.
    ''' </summary>
    ''' <param name="Int_UserAUID"></param>
    ''' <param name="UserFaithVag"></param>
    ''' <param name="ServerFileName"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <WebMethod()> _
    Public Function DeleteFile(ByVal ServerFileName As String) As Boolean

        Dim LocalFileName As String = System.Web.Hosting.HostingEnvironment.MapPath("~") & "/UpLoadFiles/" & ServerFileName
        If IO.File.Exists(LocalFileName) Then
            Try
                IO.File.Delete(LocalFileName)
                Return True
            Catch
                Return False
            End Try
        End If
        Return False

    End Function

客户端:

    '===================================================================
    '                            事件调用例子           MSTOP
    '===================================================================
    'Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    '    P_SqlWebServices.LoadFileByBlock("C:\Windows2000.vmdk", "Windows2000.vmdk")
    'End Sub
    '
    'Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    '    P_SqlWebServices.UpdateFileByBlock("E:\VMSYS\Windows2000\Windows2000.vmdk", "Windows2000.vmdk")
    'End Sub

    'Private Sub Stock_BillOrder_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    '    AddHandler P_SqlWebServices.Ev_UpdateFileByBlock, AddressOf FileByBlock
    '    AddHandler P_SqlWebServices.Ev_LoadFileByBlock, AddressOf FileByBlock
    'End Sub
    '
    'Sub FileByBlock(ByVal i As Integer, ByVal b As Integer)
    '    ProgressBar1.Maximum = b
    '    ProgressBar1.Value = i + 1
    'End Sub
    '===================================================================

    ''' <summary>
    ''' 分块上传事件.
    ''' </summary>
    ''' <param name="BlockID">当前上传的块.从0开始编号.</param>
    ''' <param name="BlockMax">总块数.</param>
    ''' <remarks></remarks>
    Public Event Ev_UpdateFileByBlock(ByVal BlockID As Int32, ByVal BlockMax As Int32)
    Const Con_BlockSize As Int32 = 1024 * 1024
    ''' <summary>
    ''' 分块上传文件到 WEB 服务器.
    ''' </summary>
    ''' <param name="LocalFileName">上传的本地文件名</param>
    ''' <param name="ServerFileName">服务器文件名(可以带目录).如: DOC\msizap.doc.</param>
    ''' <param name="BlockSize">每块大小.默认为 1M 字节.</param>
    ''' <param name="OverlayServer">如果服务器上已存在该文件,是否覆盖.</param>
    ''' <returns> 成功 TRUE 失败 FALSE </returns>
    ''' <remarks></remarks>
    Public Function UpdateFileByBlock(ByVal LocalFileName As String, _
                                      ByVal ServerFileName As String, _
                                      Optional ByVal BlockSize As Int32 = Con_BlockSize, _
                                      Optional ByVal OverlayServer As Boolean = True) As Boolean

        If Not IO.File.Exists(LocalFileName) Then
            Return False
        End If

        If BlockSize <= 1024 Then BlockSize = Con_BlockSize

        Dim FileByte() As Byte
        Dim RValue As Int32
        Dim FileLenth As Long
        Dim BlockID As Int32
        Dim LoopMax As Int32
        Dim Succeed As Boolean = True

        Dim Offset As Int32     '//偏移量
        Dim SpareLenth As Int32 '//剩余长度.
        Dim fs As FileStream = New FileStream(LocalFileName, _
                                              FileMode.Open)

        Dim Int_UserAUID As String = M_EnCrypt.CryptString(M_WebLoginInfo.Int_UserAUID)
        ServerFileName = M_EnCrypt.CryptString(ServerFileName)

        FileLenth = New IO.FileInfo(LocalFileName).Length
        LoopMax = FileLenth \ BlockSize + IIf(FileLenth Mod BlockSize > 0, 1, 0)
        For BlockID = 0 To LoopMax - 1
            Erase FileByte
            Offset = BlockID * BlockSize
            SpareLenth = FileLenth - BlockID * BlockSize '//剩余字节数.
            If SpareLenth <= BlockSize Then
                ReDim FileByte(SpareLenth - 1)
                fs.Seek(Offset, SeekOrigin.Begin)
                'fs.Position = Offset
                fs.Read(FileByte, 0, SpareLenth)
                RValue = M_Service.UpdateFileByBlock(ServerFileName, _
                                                     OverlayServer, _
                                                     BlockID, _
                                                     FileByte)
                Succeed = Succeed And (RValue = 0)
                RaiseEvent Ev_UpdateFileByBlock(BlockID, LoopMax)
            Else
                ReDim FileByte(BlockSize - 1)
                fs.Seek(Offset, SeekOrigin.Begin)
                'fs.Position = Offset
                fs.Read(FileByte, 0, BlockSize)

                RValue = M_Service.UpdateFileByBlock(ServerFileName, _
                                                     OverlayServer, _
                                                     BlockID, _
                                                     FileByte)
                Succeed = Succeed And (RValue = 0)
                RaiseEvent Ev_UpdateFileByBlock(BlockID, LoopMax)

            End If
            System.Windows.Forms.Application.DoEvents()

            If Succeed = False Then
                fs.Close()
                '//如果上传失败.删除上传的文件.
                M_Service.DeleteFile(ServerFileName)
                Exit For
            End If
        Next

        fs.Close()

        Return Succeed

    End Function

    Public Event Ev_LoadFileByBlock(ByVal BlockID As Int32, ByVal BlockMax As Int32)

    ''' <summary>
    ''' 分块从WEB服务器下载文件.
    ''' </summary>
    ''' <param name="LocalFileName">保存到本地的文件名.</param>
    ''' <param name="ServerFileName">要下载的服务器端文件名.</param>
    ''' <param name="BlockSize">每次传输的文件块大小</param>
    ''' <param name="OverlayLocal">如果文件本地存在了,是否覆盖.默认为 TRUE .</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function LoadFileByBlock(ByVal LocalFileName As String, _
                                    ByVal ServerFileName As String, _
                                    Optional ByVal BlockSize As Int32 = Con_BlockSize, _
                                    Optional ByVal OverlayLocal As Boolean = True) As Boolean
        Dim MaxBlock As Int32
        Dim BlockID As Int32 = 0
        Dim FileByte() As Byte

        If IO.File.Exists(LocalFileName) Then
            If Not OverlayLocal Then
                Return False
            End If
        End If

        If BlockSize <= 1024 Then BlockSize = Con_BlockSize

        Dim Int_UserAUID As String = M_EnCrypt.CryptString(M_WebLoginInfo.Int_UserAUID)
        ServerFileName = M_EnCrypt.CryptString(ServerFileName)

        MaxBlock = M_Service.LoadFileSplit(ServerFileName, _
                                           BlockSize)
        If MaxBlock > 0 Then

            If IO.File.Exists(LocalFileName) AndAlso OverlayLocal Then
                Try
                    IO.File.Delete(LocalFileName)
                Catch
                    Return False
                End Try
            End If

            Dim FileStream As System.IO.FileStream = New System.IO.FileStream(LocalFileName, _
                                                                              IO.FileMode.CreateNew)

            For BlockID = 0 To MaxBlock - 1

                FileByte = M_Service.LoadFileByBlock(BlockID, _
                                                     BlockSize, _
                                                     ServerFileName)
                If FileByte Is Nothing OrElse FileByte.Length = 0 Then
                    FileStream.Close()
                    Try
                        IO.File.Delete(LocalFileName) '//如果失败,删除本地文件.
                    Catch
                        '//
                    End Try
                    Return False
                End If
                RaiseEvent Ev_LoadFileByBlock(BlockID, MaxBlock)
                FileStream.Write(FileByte, 0, FileByte.Length)
                System.Windows.Forms.Application.DoEvents()
            Next

            FileStream.Close()

        End If

        Return True

    End Function

 

posted @ 2013-03-06 09:59  therockthe  阅读(619)  评论(0)    收藏  举报