我正在尝试用ftp创建一个下载客户端,我仍然试图找出最好的我有但是我卡住了因为我按照指南但它只显示它已经下载了多少字节,我怎么能改变它到gb?以及如何添加下载速度?
Imports System.Net
Public Class MainForm
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Control.CheckForIllegalCrossThreadCalls = False
End Sub
Private Sub btnBrowseSave_Click(sender As Object, e As EventArgs) Handles btnBrowseSave.Click
Dim newFolder As New FolderBrowserDialog
If newFolder.ShowDialog = Windows.Forms.DialogResult.OK Then
txtSavePath.Text = newFolder.SelectedPath
End If
End Sub
Private Sub btnDownload_Click(sender As Object, e As EventArgs) Handles btnDownload.Click
bWorker.RunWorkerAsync()
End Sub
Private Sub bWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bWorker.DoWork
Dim buffer(1023) As Byte
Dim bytesIn As Integer
Dim totalBytesIn As Integer
Dim output As IO.Stream
Dim flLength As Integer
Try
Dim FTPRequest As FtpWebRequest = DirectCast(WebRequest.Create(txtFilePath.Text), FtpWebRequest)
FTPRequest.Credentials = New NetworkCredential(txtFTPUsername.Text, txtFTPPassword.Text)
FTPRequest.Method = Net.WebRequestMethods.Ftp.GetFileSize
flLength = CInt(FTPRequest.GetResponse.ContentLength)
lblFileSize.Text = flLength & " bytes"
Catch ex As Exception
End Try
Try
Dim FTPRequest As FtpWebRequest = DirectCast(WebRequest.Create(txtFilePath.Text), FtpWebRequest)
FTPRequest.Credentials = New NetworkCredential(txtFTPUsername.Text, txtFTPPassword.Text)
FTPRequest.Method = WebRequestMethods.Ftp.DownloadFile
Dim stream As System.IO.Stream = FTPRequest.GetResponse.GetResponseStream
Dim OutputFilePath As String = txtSavePath.Text & "\" & IO.Path.GetFileName(txtFilePath.Text)
output = System.IO.File.Create(OutputFilePath)
bytesIn = 1
Do Until bytesIn < 1
bytesIn = stream.Read(buffer, 0, 1024)
If bytesIn > 0 Then
output.Write(buffer, 0, bytesIn)
totalBytesIn += bytesIn
lblDownloadedBytes.Text = totalBytesIn.ToString & " bytes"
If flLength > 0 Then
Dim perc As Integer = (totalBytesIn / flLength) * 100
bWorker.ReportProgress(perc)
End If
End If
Loop
output.Close()
stream.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub bWorker_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bWorker.ProgressChanged
pBar.Value = e.ProgressPercentage
lblPercent.Text = e.ProgressPercentage.ToString & "%"
End Sub
Private Sub bWorker_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bWorker.RunWorkerCompleted
MsgBox("Download Complete!")
End Sub
End Class
答案 0 :(得分:0)
1 KB = 2 10 字节= 1,024字节
1 MB = 2 10 KB = 2 20 字节= 1,048,576字节
1 GB = 2 10 MB = 2 30 字节= 1,073,741,824字节
1 TB = 2 10 GB = 2 40 字节= 1,099,511,627,776字节
下一个单位是Petabytes PB和Exabytes EB(可能是未来的计算机世代?)。
这是一个格式化字节数的函数。它会自动确定适当的单位:
Public Function FormatBytes(ByVal bytes As Long) As String
Dim sizes As String() = {"B", "KB", "MB", "GB", "TB", "PB", "EB"}
Dim order As Integer = 0
Dim len As Double = bytes
While len >= 1024 AndAlso order + 1 < sizes.Length
order += 1
len = len / 1024
End While
Return String.Format("{0:0.0} {1}", len, sizes(order))
End Function
使用以下命令初始化worker:
bWorker.WorkerReportsProgress = True
您还可以将字节数而不是百分比传递给ReportProgress
方法。 BackgroundWorker不关心。因为大文件可能超过Integer.MaxValue
而不是totalBytesIn As Long
声明Integer
并将KB中的进度传递给ReportProgress
方法:
bWorker.ReportProgress(CInt(totalBytesIn / 1024))
在ProgressChanged
事件处理程序中:
Private Sub bWorker_ProgressChanged(ByVal sender As Object, _
ByVal e As ProgressChangedEventArgs) _
Handles bWorker.ProgressChanged
Me.txtProgress.Text = FormatBytes(1024 * e.ProgressPercentage)
' More code to come here ... (see below)
End Sub
至于你可以使用System.Diagnostics.Stopwatch
的速度。它会显示经过的时间。
Dim stopwatch As New System.Diagnostics.Stopwatch()
stopwatch.Start()
然后在bWorker_ProgressChanged
:
Dim elapsedSeconds As Double = stopwatch.ElapsedMilliseconds / 1000
If elapsedSeconds > 0 Then
Dim speed As Double = bytes / elapsedSeconds
lblSpeed.Text = FormatBytes(CInt(speed)) & " / s"
End If
进度的最终版本更改了事件处理程序:
Private Sub bWorker_ProgressChanged(ByVal sender As Object, _
ByVal e As System.ComponentModel.ProgressChangedEventArgs) _
Handles bWorker.ProgressChanged
Dim bytes As Long = 1024 * e.ProgressPercentage
'Can exceed 100% beacause of rounding effects
Dim percent As Integer = Math.Min(100, CInt(100 * bytes \ flLength))
pBar.Value = percent
lblPercent.Text = percent & "%"
lblDownloadedBytes.Text = FormatBytes(bytes)
Dim elapsedSeconds As Double = stopwatch.ElapsedMilliseconds / 1000
If elapsedSeconds > 0 Then
Dim speed As Double = bytes / elapsedSeconds
lblSpeed.Text = FormatBytes(CInt(speed)) & " / s"
End If
End Sub
如果您在表单中声明flLength
而不是局部变量,您也可以计算并显示bWorker_ProgressChanged
中的百分比。
由于您无法理解我的答案,这里是完整的代码。在可能的情况下,我保持您的代码不变,并使用注释('===
)标记我的更改。 (到目前为止,我只有上面的代码片段,所以我必须创建一个包含所有必需控件的表单。它经过测试并且有效):
Imports System.Net
Public Class MainForm
Dim flLength As Long '=== As Form variable instead as local variable and As Long.
Dim stopwatch As New System.Diagnostics.Stopwatch() '=== New variable.
Private Sub MainForm_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
Control.CheckForIllegalCrossThreadCalls = False
End Sub
Private Sub btnBrowseSave_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnBrowseSave.Click
Dim newFolder As New FolderBrowserDialog
If newFolder.ShowDialog = Windows.Forms.DialogResult.OK Then
txtSavePath.Text = newFolder.SelectedPath
End If
End Sub
Private Sub btnDownload_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnDownload.Click
bWorker.RunWorkerAsync()
End Sub
Private Sub bWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bWorker.DoWork
Dim buffer(1023) As Byte
Dim bytesIn As Integer
Dim totalBytesIn As Long '=== As Long instead of Integer
Dim output As IO.Stream
'Dim flLength As Integer '=== Now as form variable
Try
Dim FTPRequest As FtpWebRequest = DirectCast(WebRequest.Create(txtFilePath.Text), FtpWebRequest)
FTPRequest.Credentials = New NetworkCredential(txtFTPUsername.Text, txtFTPPassword.Text)
FTPRequest.Method = Net.WebRequestMethods.Ftp.GetFileSize
flLength = CInt(FTPRequest.GetResponse.ContentLength)
lblFileSize.Text = flLength & " bytes"
Catch ex As Exception
End Try
Try
stopwatch.Start() '=== Start Stopwatch
Dim FTPRequest As FtpWebRequest = DirectCast(WebRequest.Create(txtFilePath.Text), FtpWebRequest)
FTPRequest.Credentials = New NetworkCredential(txtFTPUsername.Text, txtFTPPassword.Text)
FTPRequest.Method = WebRequestMethods.Ftp.DownloadFile
Dim stream As System.IO.Stream = FTPRequest.GetResponse.GetResponseStream
Dim OutputFilePath As String = txtSavePath.Text & "\" & IO.Path.GetFileName(txtFilePath.Text)
output = System.IO.File.Create(OutputFilePath)
bytesIn = 1
Do Until bytesIn < 1
bytesIn = stream.Read(buffer, 0, 1024)
If bytesIn > 0 Then
output.Write(buffer, 0, bytesIn)
totalBytesIn += bytesIn
lblDownloadedBytes.Text = totalBytesIn.ToString & " bytes"
If flLength > 0 Then
'=== Moved to bWorker_ProgressChanged.
'Dim perc As Integer = (totalBytesIn / flLength) * 100
'=== Now reports downloaded bytes in KB instead of percent.
bWorker.ReportProgress(CInt(totalBytesIn / 1024))
End If
End If
Loop
output.Close()
stream.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
'=== Completely reworked
Private Sub bWorker_ProgressChanged(ByVal sender As Object, _
ByVal e As System.ComponentModel.ProgressChangedEventArgs) _
Handles bWorker.ProgressChanged
Dim bytes As Long = 1024 * e.ProgressPercentage
'Can exceed 100% beacause of rounding effects
Dim percent As Integer = Math.Min(100, CInt(100 * bytes \ flLength))
pBar.Value = percent
lblPercent.Text = percent & "%"
lblDownloadedBytes.Text = FormatBytes(bytes)
Dim elapsedSeconds As Double = stopwatch.ElapsedMilliseconds / 1000
If elapsedSeconds > 0 Then
Dim speed As Double = bytes / elapsedSeconds
lblSpeed.Text = FormatBytes(CInt(speed)) & " / s"
End If
End Sub
Private Sub bWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bWorker.RunWorkerCompleted
MsgBox("Download Complete!")
End Sub
'=== New Function
Private Function FormatBytes(ByVal bytes As Long) As String
Dim sizes As String() = {"B", "KB", "MB", "GB", "TB", "PB", "EB"}
Dim order As Integer = 0
Dim len As Double = bytes
While len >= 1024 AndAlso order + 1 < sizes.Length
order += 1
len = len / 1024
End While
Return String.Format("{0:0.0} {1}", len, sizes(order))
End Function
End Class