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
浙公网安备 33010602011771号