Whats the best download method for vb? - vb.net

I am trying to make a download client with ftp and im still trying to find out whats the best i have but im in stuck because i followed a guide but it only show how much its have downloaded in bytes, how can i change it to gb? and how can i add a download speed?
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

1 KB = 210 bytes = 1,024 bytes
1 MB = 210 KB = 220 bytes = 1,048,576 bytes
1 GB = 210 MB = 230 bytes = 1,073,741,824 bytes
1 TB = 210 GB = 240 bytes = 1,099,511,627,776 bytes
The next units are Petabytes PB and Exabytes EB (maybe in future computer generations?).
Here is a function that formats the byte numbers. It determines the appropriate unit automatically:
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
Initialize the worker with:
bWorker.WorkerReportsProgress = True
You can also pass the number of bytes instead of a percentage to the ReportProgress method. The BackgroundWorker doesn't care. Because big files might exceed Integer.MaxValue declare totalBytesIn As Long instead as of Integer and pass the progress in KB to the ReportProgress method:
bWorker.ReportProgress(CInt(totalBytesIn / 1024))
In the ProgressChanged event handler:
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
As for the speed you could use a System.Diagnostics.Stopwatch. It shows you the elapsed time.
Dim stopwatch As New System.Diagnostics.Stopwatch()
stopwatch.Start()
And then in 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
The final version of the progress changed event handler:
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
And if you declare flLength in the Form instead as local variable, you can calculate and display the percentages in bWorker_ProgressChanged as well.
As you have troubles understanding my answer, here is the complete code. Where possible I kept your code as is and marked my changes with comments ('===). (I had only my code snippets from above until now, so I had to create a form with all the required controls. It's tested and it works):
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
See: How to: Use a Background Worker

Related

Save/Load BackgroundWorker Progress in vb.net

I am creating a file downloader using backgroundworker & i want to save the progress of backgroundworker so that when i restart the application, on resume, it start the download where i closed last time.
Any help ?
Here is My code for Downloader
Public Class cls_FileDownloader
Dim FileSave As String
Delegate Sub DownloadFIlesafe(ByVal Cancelled As Boolean)
Delegate Sub ChangeTextsSafe(ByVal length As Long, ByVal position As Double, ByVal percent As Long, ByVal speed As Long)
Private Sub cls_FileDownloader_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Text = ""
btn_Cancel.Enabled = False
End Sub
Private Sub btn_Download_Click(sender As Object, e As EventArgs) Handles btn_Download.Click
If Me.txt_Url.Text <> "" Then
Me.SaveFile.FileName = txt_Url.Text.Split("\"c)(txt_Url.Text.Split("\"c).Length - 1)
If SaveFile.ShowDialog = System.Windows.Forms.DialogResult.OK Then
FileSave = SaveFile.FileName
SaveFile.FileName = ""
lbl_SaveTO.Text = "Save To:" & FileSave
txt_Url.Enabled = False
btn_Download.Enabled = False
btn_Cancel.Enabled = True
bg_Worker.RunWorkerAsync()
End If
Else
MessageBox.Show("Please Insert valid file path", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
End Sub
Private Sub bg_Worker_DoWork(sender As Object, e As DoWorkEventArgs) Handles bg_Worker.DoWork
Dim response As FileWebResponse
Dim request As FileWebRequest
Try
request = WebRequest.Create(txt_Url.Text)
response = request.GetResponse
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Dim cancelDelegate As New DownloadFIlesafe(AddressOf Download_Complete)
Me.Invoke(cancelDelegate, True)
Exit Sub
End Try
Dim length As Long = response.ContentLength
Dim safedelegate As New ChangeTextsSafe(AddressOf ChangeTexts)
Me.Invoke(safedelegate, length, 0, 0, 0)
Dim writeStream As New IO.FileStream(Me.FileSave, IO.FileMode.Create)
Dim nRead As Double
'To calculate the download speed
Dim speedtimer As New Stopwatch
Dim currentspeed As Long = -1
Dim readings As Integer = 0
Do
If bg_Worker.CancellationPending Then 'If user abort download
Exit Do
End If
speedtimer.Start()
Dim readBytes(4095) As Byte
Dim bytesread As Long = response.GetResponseStream.Read(readBytes, 0, 4096)
nRead += bytesread
Dim percent As Long = (nRead * 100) / length
Me.Invoke(safedelegate, length, nRead, percent, currentspeed)
If bytesread = 0 Then Exit Do
writeStream.Write(readBytes, 0, bytesread)
speedtimer.Stop()
readings += 1
If readings >= 5 Then 'For increase precision, the speed it's calculated only every five cicles
currentspeed = 20480 / (speedtimer.ElapsedMilliseconds / 1000)
speedtimer.Reset()
readings = 0
End If
Loop
'Close the streams
response.GetResponseStream.Close()
writeStream.Close()
If Me.bg_Worker.CancellationPending Then
IO.File.Delete(Me.FileSave)
Dim cancelDelegate As New DownloadFIlesafe(AddressOf Download_Complete)
Me.Invoke(cancelDelegate, True)
Exit Sub
End If
Dim completeDelegate As New DownloadFIlesafe(AddressOf Download_Complete)
Me.Invoke(completeDelegate, False)
End Sub

Make specific randomly generated codes with timer

I would like to make randomly generated codes when a timer is finished.
But I would like to use this code ABCDEFGHIJKLOMNOPQRSTUVWXYZ0123456789
on this format XXXX-XXXX-XXXX (replace X with a randomly generated number/letter)
And I would like to insert the code in this
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
ProgressBar1.Increment(3)
If ProgressBar1.Value = 100 Then
TextBox1.Text = "replace textbox by code"
Timer1.Stop()
End If
End Sub
Here's a solution using LINQ.
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
ProgressBar1.Increment(3)
If ProgressBar1.Value = 100 Then
Dim chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
Dim random = New Random()
Dim num1 = New String(Enumerable.Repeat(chars, 4).Select(Function(s) s(random.Next(s.Length))).ToArray())
Dim num2 = New String(Enumerable.Repeat(chars, 4).Select(Function(s) s(random.Next(s.Length))).ToArray())
Dim num3 = New String(Enumerable.Repeat(chars, 4).Select(Function(s) s(random.Next(s.Length))).ToArray())
Dim result = num1 & "-" & num2 & "-" & num3
TextBox1.Text = result
Timer1.Stop()
End If
End Sub
With this, you'd just change your TextBox1.Text = to point to the getNewRandomString() function.
Private Function getNewRandomString() As String
Dim sb As New StringBuilder
For i = 1 To 3
For j = 1 To 4
sb.Append(getNewRandomLetter())
Next
sb.Append("-")
Next
Return sb.ToString.Trim("-")
End Function
Private Function getNewRandomLetter() As Char
Dim chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
Return (chars(GetRandom(0, chars.Length - 1)))
End Function
Public Function GetRandom(ByVal Min As Integer, ByVal Max As Integer) As Integer
Static Generator As System.Random = New System.Random()
Return Generator.Next(Min, Max + 1)
End Function

Making a string from a listbox

I have 2 projects, one which has a highscorelist stored on it, and one which tries to add highscores to that list and retrieve all items on the list. Trying to put items on the list works good, but retrieving the list doesn't work well. Here's the code:
Option Strict On
Option Explicit On
Imports System.Net.Sockets
Imports System.Threading
Public Class Main
Dim server As New TcpListener(45888)
Dim client As New TcpClient
Dim stream As NetworkStream
Dim connected As Boolean
Private Sub cmd_start_Click(sender As Object, e As EventArgs) Handles cmd_start.Click
server.Start()
cmd_start.Enabled = False
cmd_stop.Enabled = True
lbl_status.Text = "Running"
lbl_status.ForeColor = Color.Green
tmr.Start()
End Sub
Private Sub cmd_stop_Click(sender As Object, e As EventArgs) Handles cmd_stop.Click
server.Stop()
cmd_start.Enabled = True
cmd_stop.Enabled = False
lbl_status.Text = "Not running"
lbl_status.ForeColor = Color.Red
tmr.Stop()
End Sub
Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
connected = False
CheckForIllegalCrossThreadCalls = False
End Sub
Dim x As Integer = 0
Private Sub tmr_Tick(sender As Object, e As EventArgs) Handles tmr.Tick
If server.Pending Then
client = server.AcceptTcpClient()
stream = client.GetStream()
tmr.Stop()
read()
Else
tmr.Start()
End If
lbl_mseconds.Text = "Relative time: " & x
x += 1
End Sub
Private Sub SendMessage(message As String)
Dim sendtext() As Byte = System.Text.Encoding.ASCII.GetBytes(message)
stream.Write(sendtext, 0, sendtext.Length)
stream.Flush()
End Sub
Private Sub read()
Dim rec(client.ReceiveBufferSize) As Byte
stream.Read(rec, 0, client.ReceiveBufferSize)
Dim rectext As String = System.Text.Encoding.ASCII.GetString(rec)
If rectext.Contains("#1#") Then
rectext = rectext.Substring(3)
If rectext.Split(CChar("-"))(0).Length = 2 Then rectext = "0" & rectext
If rectext.Split(CChar("-"))(0).Length = 1 Then rectext = "00" & rectext
listbox_highscores.Items.Add(rectext)
ElseIf rectext.Contains("#2#") Then
Dim tosend As String = listbox_highscores.Items(0).ToString
For i = 1 To listbox_highscores.Items.Count - 1
tosend &= "," & listbox_highscores.Items(i).ToString
Next
MsgBox(tosend)
SendMessage(tosend)
End If
tmr.Start()
End Sub
End Class
On the other project I have this:
Dim server As New TcpListener(45888)
Dim client As New TcpClient
Dim stream As NetworkStream
Friend Sub sendHighscore(name As String, score As Integer)
Try
client.Connect("192.168.1.127", 45888)
Catch ex As Exception
Exit Sub
End Try
stream = client.GetStream()
Dim sendtext() As Byte = Encoding.ASCII.GetBytes("#1#" & score & "-" & name)
stream.Write(sendtext, 0, sendtext.Length)
client = New TcpClient
End Sub
Friend Sub getHighscoreList()
ListBox_highscores.Items.Clear()
Try
client.Connect("192.168.1.127", 45888)
Catch ex As Exception
ListBox_highscores.Items.Add("Couldn't connect")
Exit Sub
End Try
stream = client.GetStream()
Dim sendtext() As Byte = Encoding.ASCII.GetBytes("#2#")
stream.Write(sendtext, 0, sendtext.Length)
client = New TcpClient
read()
End Sub
Private Sub read()
Dim rec(client.ReceiveBufferSize) As Byte
stream.Read(rec, 0, client.ReceiveBufferSize)
Dim rectext As String = Encoding.ASCII.GetString(rec)
Label2.Text = rectext
For Each item In rectext.Split(",")
ListBox_highscores.Items.Add(item)
Next
End Sub
Then when I use the sub sendHighscore() with a name and score, everything perfectly works and it shows in the other project on the list, but when I use the sub getHighscoreList() the list on the second project only contains the first item from the first list. Does someone has ideas?
Edit: Original answer removed entirely because it wasn't actually the problem (although it did offer improvements). My answer was nearly identical to this one anyway.
After analyzing this project much more closely, the problem with the For..Next loop not returning the expected results is because the strings are being sent back and forth as byte arrays in buffers much larger than necessary (client.ReceiveBufferSize). The actual "strings" received contain large amounts of non-printable characters (garbage) added to the end to fill the buffer. The quick and dirty solution is to remove all non-printable characters:
rectext = System.Text.RegularExpressions.Regex.Replace(rectext, _
"[^\u0020-\u007F]", String.Empty)
The whole Sub would read like this:
Private Sub read()
Dim rec(client.ReceiveBufferSize) As Byte
stream.Read(rec, 0, client.ReceiveBufferSize)
Dim rectext As String = System.Text.Encoding.ASCII.GetString(rec)
If rectext.Contains("#1#") Then
rectext = rectext.Substring(3)
If rectext.Split(CChar("-"))(0).Length = 2 Then rectext = "0" & rectext
If rectext.Split(CChar("-"))(0).Length = 1 Then rectext = "00" & rectext
rectext = System.Text.RegularExpressions.Regex.Replace(rectext, "[^\u0020-\u007F]", String.Empty)
listbox_highscores.Items.Add(rectext)
ElseIf rectext.Contains("#2#") Then
Dim tosend As String = listbox_highscores.Items(0).ToString
For i As Integer = 1 To (listbox_highscores.Items.Count - 1)
tosend &= "," & listbox_highscores.Items(i).ToString
Next
SendMessage(tosend)
End If
tmr.Start()
End Sub
Try this, your comma's are off as well...
Dim tosend As String = String.Empty
Dim intCount As Integer = 0
For i As Integer = 0 To listbox.Items.Count - 1
If intCount >= 1 Then
tosend &= "," & listbox.Items(i).ToString
Else
tosend &= listbox.Items(i).ToString
intCount += 1
End If
Next
MessageBox.Show(tosend)
Screenshot THAT IT WORKS!

code modified lines added

I have data like this
date value
24sep2014 2:23:01 0.1
24sep2014 2:23:02 0.3
24sep2014 2:23:03 0.2
24sep2014 2:23:04 0.3
These are not coma seprated value. I wanted to write in CSV file. Apend the value for next row.
1)How to open file only once here. when it run next time file name has to change to other name
2) How to append the next values
Imports System
Imports System.IO.Ports
Imports System.ComponentModel
Imports System.Threading
Imports System.Drawing
Imports System.Windows.Forms.DataVisualization.Charting
Public Class Form1
Dim myPort As Array
Dim Distance As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
myPort = IO.Ports.SerialPort.GetPortNames()
PortComboBox.Items.AddRange(myPort)
BaudComboBox.Items.Add(9600)
BaudComboBox.Items.Add(19200)
BaudComboBox.Items.Add(38400)
BaudComboBox.Items.Add(57600)
BaudComboBox.Items.Add(115200)
ConnectButton.Enabled = True
DisconnectButton.Enabled = False
Chart1.Series.Clear()
Chart1.Titles.Add("Demo")
'Create a new series and add data points to it.
Dim s As New Series
s.Name = "CURRENT"
s.ChartType = SeriesChartType.Line
End Sub
Private Sub ConnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConnectButton.Click
SerialPort1.PortName = PortComboBox.Text
SerialPort1.BaudRate = BaudComboBox.Text
SerialPort1.Open()
Timer1.Start()
Timer2.Start()
'lblMessage.Text = PortComboBox.Text & " Connected."
ConnectButton.Enabled = False
DisconnectButton.Enabled = True
End Sub
Private Sub DisconnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DisconnectButton.Click
SerialPort1.Close()
DisconnectButton.Enabled = False
ConnectButton.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim counter As Integer
counter = 0
Try
SerialPort1.Write("c")
System.Threading.Thread.Sleep(250)
Dim k As Double
Dim distance As String = SerialPort1.ReadLine()
k = CDbl(distance)
ListBoxSensor.Text = k
Dim s As New Series
s.Points.AddXY(1000, k)
Chart1.Series.Add(s)
Dim headerText = ""
Dim csvFile As String = Path.Combine(My.Application.Info.DirectoryPath, "Current.csv")
If Not File.Exists(csvFile)) Then
headerText = "Date& time ,Current"
End If
Using outFile = My.Computer.FileSystem.OpenTextFileWriter(csvFile, True)
If headerText.Length > 0 Then
outFile.WriteLine(headerText)
End If
Dim y As String = DateAndTime.Now
Dim x As String = y + "," + distance
outFile.WriteLine(x)
End Using
Catch ex As Exception
End Try
End Sub
Private Sub Relay_ON_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Relay_ON.Click
SerialPort1.Write("1")
End Sub
Private Sub Relay_Off_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Relay_Off.Click
SerialPort1.Write("0")
End Sub
End Class
Here i am opening file again and again. that reason i can store only one value
# steve error
The second parameter of OpenTextFileWriter allows to append instead of overwrite your file.
So it is simply a matter to check if the file exists (so you insert the header names) and then write your data
Dim headerText = ""
Dim csvFile As String = Path.Combine(My.Application.Info.DirectoryPath, "Current.csv")
If Not File.Exists(csvFile) Then
headerText = "Date& time ,Current"
End If
Using outFile = My.Computer.FileSystem.OpenTextFileWriter(csvFile, True)
If headerText.Length > 0 Then
outFile.WriteLine(headerText)
End If
Dim y As String = DateAndTime.Now
Dim x As String = y + "," + distance
outFile.WriteLine(x)
End Using
Notice the Using Statement to be sure to close and dispose the file resource also in case of exceptions.
However given the simple text that need to be written you could also choose to use the method WriteAllText
Dim headerText = ""
Dim csvFile As String = Path.Combine(My.Application.Info.DirectoryPath, "Current.csv")
If Not File.Exists(csvFile) Then
headerText = "Date& time ,Current" & Environment.NewLine
End If
Dim y As String = DateAndTime.Now
Dim x As String = headerText & y & "," + distance & Environment.NewLine
My.Computer.FileSystem.WriteAllText(csvFile, x, True)

Measuring download speed

I'm downloading a file using the following:
Dim client As WebClient = New WebClient()
client.DownloadFileAsync(New Uri("http://cachefly.cachefly.net/100mb.test"), "C:\Users\Dir\100mb.test")
The file downloads and saves into the C://Users/Dir/100mb.test, but while its downloading I would like to display the download speed in a label. How can I do this? I have read many tutorials, but most of them doesn't works or are outdated. I'm a newbie with vb.net, so I can't really write something on my own, could you give me any solutions?
May I suggest something different?
Imports System.Net
Public Class Form1
Private tmp = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Temp, "snafu.fubar")
Private Downloading As Boolean = False
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Downloading Then Exit Sub
Downloading = True
Dim wc As New WebClient
AddHandler wc.DownloadProgressChanged, AddressOf wc_ProgressChanged
AddHandler wc.DownloadFileCompleted, AddressOf wc_DownloadDone
wc.DownloadFileAsync(New Uri("http://cachefly.cachefly.net/100mb.test"), tmp, Stopwatch.StartNew)
End Sub
Private Sub wc_DownloadDone(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs)
Downloading = False
End Sub
Private Sub wc_ProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs)
Me.Label1.Text = (e.BytesReceived / (DirectCast(e.UserState, Stopwatch).ElapsedMilliseconds / 1000.0#)).ToString("#")
End Sub
End Class
Because it makes no sense to determine the speed by the last chunk of bytes received, but instead you measure the total number of bytes and divide by the TOTAL time. Passing a stopwatch instance to the eventhandler has the advantage that it doesnt 'spoil' your class code - it''s visible only where it's needed.
This will give you percentage in the mean time. You could probably calculate from the percentage given a start time using DateTime.Now the speed in which it the download is taking:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
Dim client As WebClient = New WebClient()
AddHandler client.DownloadProgressChanged, AddressOf ProgChanged
client.DownloadFileAsync(New Uri("http://cachefly.cachefly.net/100mb.test"), "C:\Users\Dir\100mb.test")
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub ProgChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)
Dim progressPercentage As Integer = e.ProgressPercentage
End Sub
Define globals:
Dim lastUpdate As DateTime
Dim lastBytes As Long = 0
You'll need to assign an Event for progress:
Dim client As WebClient = New WebClient()
client.DownloadFileAsync(New Uri("http://cachefly.cachefly.net/100mb.test"), "C:\Users\Dir\100mb.test")
client.DownloadProgressChanged += Function(sender, e) progressChanged(e.BytesReceived)
The Event:
Private Sub progressChanged(bytes As Long)
If lastBytes = 0 Then
lastUpdate = DateTime.Now
lastBytes = bytes
Return
End If
Dim now = DateTime.Now
Dim timeSpan = now - lastUpdate
If Not timeSpan.Seconds = 0
Dim bytesChange = bytes - lastBytes
Dim bytesPerSecond = bytesChange / timeSpan.Seconds
lastBytes = bytes
lastUpdate = now
End If
End Sub
And you have the calculations of bytes per second.
label.Text = bytesPerSecond.ToString() + "B/s";
Try this:
Try this only when you're downloading through a backgroundworker
Private Sub worker_DoWork(Byval sender As Object, Byval e As DoWorkEventArgs)
Dim req As WebRequest = WebRequest.Create(downloadUrl) 'Make a request for the url of the file to be downloaded
Dim resp As WebResponse = req.GetResponse 'Ask for the response
Dim fs As New FileStream(path to download to, FileMode.CreateNew) 'Create a new FileStream that writes to the desired download path
Dim buffer(8192) As Byte 'Make a buffer
Dim downloadedsize As Long = 0
Dim downloadedTime As Long = 0
Dim dlSpeed As Long = 0
Dim currentSize As Long = 0 'Size that has been downloaded
Dim totalSize As Long = req.ContentLength 'Total size of the file that has to be downloaded
Do While currentSize < totalSize
Dim read As Integer = resp.GetResponseStream.Read(buffer, 0, 8192) 'Read the buffer from the response the WebRequest gave you
fs.Write(buffer, 0, read) 'Write to filestream that you declared at the beginning of the DoWork sub
currentSize += read
downloadedSize += read
downloadedTime += 1 'Add 1 millisecond for every cycle the While field makes
If downloadedTime = 1000 Then 'Then, if downloadedTime reaches 1000 then it will call this part
dlSpeed = (downloadedSize / TimeSpan.FromMilliseconds(downloadedTime).TotalSeconds) 'Calculate the download speed by dividing the downloadedSize by the total formatted seconds of the downloadedTime
downloadedTime = 0 'Reset downloadedTime and downloadedSize
downloadedSize = 0
End If
End While
fs.Close() 'Close the FileStream first, or the FileStream will crash.
resp.Close() 'Close the response
End Sub
Sorry for not using proper formatting, but this is a solution in itself.