Sub copyfilewithprogress()
Dim path As String = Application.StartupPath & "\"
Dim mediafile As String = "Amy Diamond - What's in it for me.mp3"
Dim fi As New IO.FileInfo(mediafile)
Dim sr As New IO.FileStream(path & mediafile, IO.FileMode.Open) 'source file
Dim sw As New IO.FileStream(path & "copy of " & mediafile, IO.FileMode.Create) 'target file, defaults overwrite
Dim len As Long = sr.Length - 1
For i As Long = 0 To len
sw.WriteByte(sr.ReadByte)
If i Mod 1000 = 0 Then 'only update UI every 1 Kb copied
ProgressBar1.Value = i * 100 / len
Application.DoEvents()
End If
Next
ProgressBar1.Value = 0
End Sub
sr.close
sw.Close
FileStream with FileMode.Open requires an existing file, as documented FileNotFoundException is thrown when not.@JohnH - Aside from the progress bar, how does this function differ from file.copy? I know file.copy will return an error if the files are missing.
Yes, I realized that, so I wrote my own Exists() function to account for that.FileStream with FileMode.Open requires an existing file, as documented FileNotFoundException is thrown when not.
Of course is does, all other file IO tools use it also, including FileSystem.CopyFile. What I'm saying is that many additions has been made to .Net framework since the first version, to make common programming tasks much simpler for the developer.Actually, the filestream works perfectly (.net 4).
A plain byte copy of a file can't differ by even a single byte, if it does something is wrong.however. I saw in debug.print that the filesize can differ by one or two bytes
That's what I thought too. I think I had the debug.print in the wrong spot... It is copying perfectly now.A plain byte copy of a file can't differ by even single byte, if it does something is wrong.
Private Sub FileCopyWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles FileCopyWorker.DoWork
Try Dim temppath As String = GetDirFromPath(whatdestinationfile) & "temp"
Dim fi As New IO.FileInfo(temppath)
Dim sr As New IO.FileStream(whatoriginationfile, IO.FileMode.Open) 'source file
Dim sw As New IO.FileStream(temppath, IO.FileMode.Create) 'target file, defaults overwrite
Dim len As Long = sr.Length - 1
MessengerLogger.Info("Please wait whilst I upload " & whatoriginationfile)
Dim i As long
For i = 0 To len
If FileCopyWorker.CancellationPending Then
MessengerLogger.Error("The transfer was cancelled at: " & progress & "%.")
Exit For
End If
sw.WriteByte(sr.ReadByte)
If i Mod 1000 = 0 Then 'only update UI every 1 Kb copied
progress = i * 100 / len
FileCopyWorker.ReportProgress(progress)
Debug.Print(progress)
Application.DoEvents()
End If
Next
sr.close
sw.close
If progress = 100 then
'Debug.Print("finished:" & progress)
File.Move(temppath, whatdestinationfile)
Else
'Debug.Print("cancelled:" & progress)
File.Delete(temppath)
end if
Catch IOerror As Exception
MessengerLogger.Error("There was an error in the procedure: " & IOerror.Message & " :CopyFileWithProgress().")
End Try
End Sub
dim i as long
dim progress as long
dim m as long
dim t as long = 14
for i = 0 to t
m = i mod 1000
' console.write(vbcr & "mod=" & m)
if m = 0 then
progress = i * 100 / t
console.write(vbcr & "i =" & i & vbcr)
console.write("progress=" & progress & "%")
end if
next
i =0
progress=0%
i =0
progress=0%
i =1000
progress=71%
i =0
progress=0%
i =1000
progress=7%
i =2000
progress=14%
i =3000
progress=21%
i =4000
progress=29%
i =5000
progress=36%
i =6000
progress=43%
i =7000
progress=50%
i =8000
progress=57%
i =9000
progress=64%
i =10000
progress=71%
i =11000
progress=79%
i =12000
progress=86%
i =13000
progress=93%
i =14000
progress=100%
i =0
progress=0%
i =1000
progress=100%
i =0
progress=0%
[COLOR=#0000ff][B]Private[/B][/COLOR] [COLOR=#0000ff][B]Sub[/B][/COLOR] FileCopyWorker_DoWork([COLOR=#0000ff][B]ByVal[/B][/COLOR] sender [COLOR=#0000ff][B]As[/B][/COLOR] [COLOR=#0c8910][B]Object[/B][/COLOR], [COLOR=#0000ff][B]ByVal[/B][/COLOR] e [COLOR=#0000ff][B]As[/B][/COLOR] System.ComponentModel.DoWorkEventArgs) [COLOR=#0000ff][B]Handles[/B][/COLOR] FileCopyWorker.DoWork
whattempdestinationfile = GetDirFromPath(whatdestinationfile) & [COLOR=#f99304]"temp"[/COLOR]
[COLOR=#0000ff][B]Try[/B][/COLOR]
[COLOR=#0000ff][B]Dim[/B][/COLOR] fi [COLOR=#0000ff][B]As[/B][/COLOR] [COLOR=#fc0a02]New[/COLOR] IO.FileInfo(whattempdestinationfile)
[COLOR=#0000ff][B]Dim[/B][/COLOR] sr [COLOR=#0000ff][B]As[/B][/COLOR] [COLOR=#fc0a02]New[/COLOR] IO.FileStream(whatoriginationfile, IO.FileMode.Open) [COLOR=#a9aaa9]'source file[/COLOR]
[COLOR=#0000ff][B]Dim[/B][/COLOR] sw [COLOR=#0000ff][B]As[/B][/COLOR] [COLOR=#fc0a02]New[/COLOR] IO.FileStream(whattempdestinationfile, IO.FileMode.Create) [COLOR=#a9aaa9]'target file, defaults overwrite[/COLOR]
[COLOR=#0000ff][B]Dim[/B][/COLOR] len [COLOR=#0000ff][B]As[/B][/COLOR] [COLOR=#0c8910][B]Long[/B][/COLOR] = sr.Length - 1
MessengerLogger.Info([COLOR=#f99304]"Please wait whilst I upload "[/COLOR] & whatoriginationfile)
[COLOR=#0000ff][B]Dim[/B][/COLOR] i [COLOR=#0000ff][B]As[/B][/COLOR] [COLOR=#0c8910][B]long[/B][/COLOR]
[COLOR=#0000ff][B]For[/B][/COLOR] i = 0 [COLOR=#0000ff][B]To[/B][/COLOR] len
[COLOR=#0000ff][B]If[/B][/COLOR] FileCopyWorker.CancellationPending [COLOR=#0000ff][B]Then[/B][/COLOR]
MessengerLogger.[COLOR=#0000ff][B]Error[/B][/COLOR]([COLOR=#f99304]"The transfer was cancelled at: "[/COLOR] & progress & [COLOR=#f99304]"%."[/COLOR])
[COLOR=#0000ff][B]Exit[/B][/COLOR] [COLOR=#0000ff][B]For[/B][/COLOR]
[COLOR=#0000ff][B]End[/B][/COLOR] [COLOR=#0000ff][B]If[/B][/COLOR]
sw.WriteByte(sr.ReadByte)
progress = i * 100 / len
[COLOR=#0000ff][B]If[/B][/COLOR] i [COLOR=#fc0a02]Mod[/COLOR] 1000 = 0 [COLOR=#fc0a02]Or[/COLOR] progress = 100 [COLOR=#0000ff][B]Then[/B][/COLOR] [COLOR=#a9aaa9]'only update UI every 1 Kb copied[/COLOR]
FileCopyWorker.ReportProgress(progress)
Application.DoEvents()
[COLOR=#0000ff][B]End[/B][/COLOR] [COLOR=#0000ff][B]If[/B][/COLOR]
[COLOR=#0000ff][B]Next[/B][/COLOR]
sr.close
sw.close
[COLOR=#0000ff][B]Catch[/B][/COLOR] IOerror [COLOR=#0000ff][B]As[/B][/COLOR] Exception
MessengerLogger.[COLOR=#0000ff][B]Error[/B][/COLOR]([COLOR=#f99304]"There was an error in the procedure: "[/COLOR] & IOerror.Message & [COLOR=#f99304]" :CopyFileWithProgress()."[/COLOR])
[COLOR=#0000ff][B]End[/B][/COLOR] [COLOR=#0000ff][B]Try[/B][/COLOR]
[COLOR=#0000ff][B]End[/B][/COLOR] [COLOR=#0000ff][B]Sub[/B][/COLOR]
[\code]
If copy for example is stopped after 995 out of 1000 bytes then progress would be at 100, but copy operation was not completed.I don't understand why progress=100 wouldn't work
How could it not? The progress reporting is unrelated to the copy operation.I think the reason it doesn't copy smaller files (and it doesn't)
If an exception is thrown those are not called. Either utilize the Using statement, or put them in Finally block of the Try statement.sr.close
sw.Close
Now you are calculating percentage for each byte, which is unnecessary. While not a big waste of CPU cycles, it still is, always something to think about.I moved things around a bit
It if was better than VS IDE I would use itFastSharp - it lets you quickly evaluate expressions without using the VS IDE
Okay, I see that now. The IO functions run regardless unless the user cancels the process, in which case it gets interrupted, or there is an error, but my progressbar is only affected by the i mod part. It is important, therefore, to make sure sw.writebyte(sr.readbyte) is NOT inside the mod block.How could it not? The progress reporting is unrelated to the copy operation.
If i mod 1000 = 0 or i = len then...
Good point about the exception. I should have realized that.If an exception is thrown those are not called. Either utilize the Using statement, or put them in Finally block of the Try statement.
For i = 0 To len
If FileCopyWorker.CancellationPending Then
FileStatus = false
MessengerLogger.Warn("You cancelled the transfer at: " & progress & "%.")
Exit For
End If
sw.WriteByte(sr.ReadByte)
progress = i * 100 / len
If i Mod 1000 = 0 or i = len Then 'only update UI every 1 Kb copied
If i = len then FileStatus = true
FileCopyWorker.ReportProgress(progress)
Application.DoEvents()
End If
Next
Okay, I agree, but what do I do? How can I make sure the progressbar follows the IO stream more efficiently. Maybe mod 10000 instead of mod 1000?Now you are calculating percentage for each byte, which is unnecessary.
Why? 100% progress is something you can report after the copy loop if not cancelled. You can even do that from RunWorkerCompleted event handler.If i mod 1000 = 0 or i = len then...
I guess that depends on the file size copied. Look at Windows copy, you rarely see progress indication for a single file copy under 1mb, the operation is simply too fast and completes almost before it is possible to display a progress GUI. So time is a factor here, maybe you could disregard the particular byte progress and just look at the time since last progress update, for example only report progress once per second?How can I make sure the progressbar follows the IO stream more efficiently. Maybe mod 10000 instead of mod 1000?
Any disposable class instance is a resource. The code sample is using a TextWriter instance for example. Though Using statement is not such a good idea here, the Using block swallows all exceptions, and here you need to know if an exception is thrown.I don't understand how to use Using, unless it is a resource.
If FileCopyWorker.CancellationPending Then
FileStatus = false
MessengerLogger.Warn("You cancelled the transfer at: " & progress & "%.")
Exit For
End If
sw.WriteByte(sr.ReadByte)
If i Mod 1000 = 0 Then 'only update UI every 1 Kb copied
progress = i * 100 / len
FileCopyWorker.ReportProgress(progress)
Application.DoEvents()
End If
If i = len then FileStatus = true
Next
FileCopyWorker.RunWorkerCompleted
If filestatus then
File.Move(whattempdestinationfile, whatdestinationfile)
If GetFileSize(whatdestinationfile) = GetFileSize(whatoriginationfile) then
MessengerLogger.Info(msg_finished)
MakeThreadedNotifications() 'that is, send an email to notify someone
End If
whatprogressbar.Value = 100
Else
MessengerLogger.Warn(msg_toobad)
File.Delete(whattempdestinationfile)
End If
whatstartbutton.Enabled = True
whatcancelbutton.Enabled = False
End Sub
Do you think it is the monitoring of the byte progress that makes the action slower? I understand about the progress being too fast to monitor for small files.maybe you could disregard the particular byte progress and just look at the time since last progress update, for example only report progress once per second?