1 #Region "Microsoft.VisualBasic::3233674ce9a362af64f6394219df8a25, Microsoft.VisualBasic.Core\Net\wGetTools.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class wGetTools
35     
36     '         Properties: CurrentSize, Downloading, DownloadSpeed, TotalSize
37     
38     '         Constructor: (+1 OverloadsSub New
39     
40     '         FunctionToString
41     
42     '         Sub: __downloadTask, (+2 Overloads) Dispose, StartTask
43     
44     
45     ' /********************************************************************************/
46
47 #End Region
48
49 Imports System.IO
50 Imports System.Net
51
52 Namespace Net
53
54     ''' <summary>
55     ''' 提供一些比较详细的数据信息和事件处理
56     ''' </summary>
57     Public Class wGetTools : Implements System.IDisposable
58
59         ReadOnly downloadUrl As String
60         ReadOnly fs As FileStream
61         ReadOnly savePath As String
62
63         ''' <summary>
64         ''' Size that has been downloaded
65         ''' </summary>
66         Public ReadOnly Property CurrentSize As Long = 0
67         ''' <summary>
68         ''' Total size of the file that has to be downloaded
69         ''' </summary>
70         Public ReadOnly Property TotalSize As Long
71
72         ''' <summary>
73         ''' KB/sec
74         ''' </summary>
75         ''' <returns></returns>
76         Public ReadOnly Property DownloadSpeed As Double
77             Get
78                 Return _speedSamples.Average
79             End Get
80         End Property
81
82         Public Event DownloadProcess(wget As wGetTools, percentage As Double)
83
84         ''' <summary>
85         ''' Client status
86         ''' </summary>
87         ''' <returns></returns>
88         Public ReadOnly Property Downloading As Boolean
89
90         Sub New(downloadUrl As String, SaveFile As String)
91             Me.fs = New FileStream(SaveFile, FileMode.CreateNew) 'Create a new FileStream that writes to the desired download path
92             Me.downloadUrl = downloadUrl
93             Me.savePath = SaveFile
94         End Sub
95
96         Dim _speedSamples As List(Of Double)
97
98         Public Sub StartTask()
99             If Downloading Then Return
100
101             _Downloading = True
102             Call __downloadTask()
103             _Downloading = False
104         End Sub
105
106         Private Sub __downloadTask()
107             Dim req As WebRequest = WebRequest.Create(downloadUrl) 'Make a request for the url of the file to be downloaded
108             Dim resp As WebResponse = req.GetResponse 'Ask for the response
109
110             Dim buffer(8192) As Byte 'Make a buffer
111             Dim downloadedsize As Long = 0
112             Dim downloadedTime As Long = 0
113             Dim dlSpeed As Long = 0
114
115             _TotalSize = req.ContentLength
116             _speedSamples = New List(Of Double)
117             _CurrentSize = 0
118
119             Do While _CurrentSize < _TotalSize
120                 Dim read As Integer = resp.GetResponseStream.Read(buffer, 0, 8192) 'Read the buffer from the response the WebRequest gave you
121
122                 fs.Write(buffer, 0, read) 'Write to filestream that you declared at the beginning of the DoWork sub
123
124                 _CurrentSize += read
125
126                 downloadedsize += read
127                 downloadedTime += 1 'Add 1 millisecond for every cycle the While field makes
128
129                 If downloadedTime = 1000 Then 'Then, if downloadedTime reaches 1000 then it will call this part
130                     dlSpeed = (downloadedsize / TimeSpan.FromMilliseconds(downloadedTime).TotalSeconds) 'Calculate the download speed by dividing the downloadedSize by the total formatted seconds of the downloadedTime
131
132                     downloadedTime = 0 'Reset downloadedTime and downloadedSize
133                     downloadedsize = 0
134
135                     Call _speedSamples.Add(dlSpeed)
136
137                     RaiseEvent DownloadProcess(Me, 100 * CurrentSize / TotalSize)
138                 End If
139             Loop
140
141             fs.Close() 'Close the FileStream first, or the FileStream will crash.
142             resp.Close() 'Close the response
143         End Sub
144
145         Public Overrides Function ToString() As String
146             Return $"{downloadUrl} ==> {savePath.ToFileURL}   [{100 * _currentSize / _totalSize}%, {DownloadSpeed}KB/sec]"
147         End Function
148
149 #Region "IDisposable Support"
150         Private disposedValue As Boolean To detect redundant calls
151
152         ' IDisposable
153         Protected Overridable Sub Dispose(disposing As Boolean)
154             If Not Me.disposedValue Then
155                 If disposing Then
156                     ' TODO: dispose managed state (managed objects).
157                 End If
158
159                 ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
160                 ' TODO: set large fields to null.
161             End If
162             Me.disposedValue = True
163         End Sub
164
165         ' TODO: override Finalize() only if Dispose(disposing As Boolean) above has code to free unmanaged resources.
166         'Protected Overrides Sub Finalize()
167         '    Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
168         '    Dispose(False)
169         '    MyBase.Finalize()
170         'End Sub
171
172         ' This code added by Visual Basic to correctly implement the disposable pattern.
173         Public Sub Dispose() Implements IDisposable.Dispose
174             Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
175             Dispose(True)
176             ' TODO: uncomment the following line if Finalize() is overridden above.
177             ' GC.SuppressFinalize(Me)
178         End Sub
179 #End Region
180     End Class
181 End Namespace