candyman Posted July 8, 2005 Posted July 8, 2005 I'm attempting to make a program that will copy files reclusively in VB.NET. basically I have a function that calculates the total size of every file in the directory and sub directories then goes through all of them and calls the CopyFile function. this works alright in that my progress bar actually updates while the file is being copied instead of using filenames like I had been. It just seams to be going a lot slower. Five seconds for a 156k file as opposed to bellow three. Is there a better way? Clint Private Function CopyFile(ByVal OldFile As String, ByVal NewFile As String) Me.FileProgressbar.Value = 0 Dim FS As New FileStream(OldFile, FileMode.Open) Dim FW As New FileStream(NewFile, FileMode.CreateNew) Dim Buffer() As Byte 'Get the bytes from file to a byte array ReDim Buffer(FS.Length - 1) Me.FileProgressbar.Maximum = FS.Length FS.Read(Buffer, 0, Buffer.Length) 'Do your stuff :-) For i As Int32 = 0 To Buffer.Length - 1 Me.FileProgressbar.Value += 1 FW.WriteByte(Buffer(i)) Me.TotalProgressbar.Value += 1 Next FS.Close() FW.Close() End Function Quote
IngisKahn Posted July 8, 2005 Posted July 8, 2005 Writing one byte at a time will be painfully slow. Try writing in larger blocks, 1024 is a good size -- on average that block size yields the best speed vs number of updates. Quote "Who is John Galt?"
candyman Posted July 8, 2005 Author Posted July 8, 2005 Writing one byte at a time will be painfully slow. Try writing in larger blocks' date=' 1024 is a good size -- on average that block size yields the best speed vs number of updates.[/quote'] I changed it to write and update the progressbars every kb and that helped a lot. It copied a 75.5 Meg file 1.53125 Seconds faster then File.Copy :-) Thanks for the help. Quote
Wile Posted July 8, 2005 Posted July 8, 2005 I believe that streams have a buffer size. Maybe using the buffersize of the stream as the amount of data to copy at once would give the best results ;). I think default it is 4 kb (so your 1 kb is a lot better than a single byte :D ). Quote Nothing is as illusive as 'the last bug'.
IngisKahn Posted July 8, 2005 Posted July 8, 2005 Ya, duh, match the buffer size. Quote "Who is John Galt?"
candyman Posted July 8, 2005 Author Posted July 8, 2005 My Code with a single progressbar took 42.374 seconds to copy a 483,005 kb file, File.Copy took 46.343 seconds two progressbars: My Code: 68.28 Seconds File.Copy: 37.343 Seconds No Progressbars: Mine: 23.796 Seconds .NET: 41.499 Seconds that last one surprised me. figured that at best mine would be just as fast as File.Copy, but apparently not... Clint Quote
IngisKahn Posted July 9, 2005 Posted July 9, 2005 That will only help if you have multi disks. Quote "Who is John Galt?"
Wraith Posted July 9, 2005 Posted July 9, 2005 That will only help if you have multi disks. Not really, the IO thread can be blocked while the UI thread is updating the UI. If you mean that multiple threads won't help with the base IO then you are of course correct. Quote
ssat2k Posted July 11, 2005 Posted July 11, 2005 Private Function CopyFile(ByVal OldFile As String, ByVal NewFile As String) Dim m_aBuffer(512) As Byte Dim m_iRemotePort, m_iBytes As Int32 Me.FileProgressbar.Value = 0 Dim FS As New FileStream(OldFile, FileMode.Open) Dim FW As New FileStream(NewFile, FileMode.Create) Do While (True) m_aBuffer.Clear(m_aBuffer, 0, m_aBuffer.Length) m_iBytes = FS.Read(m_aBuffer, 0, m_aBuffer.Length) FW.Write(m_aBuffer, 0, m_iBytes) Me.FileProgressbar.Value += m_iBytes If (m_iBytes <= 0) Then Exit Do End If Loop FS.Close() FW.Close() End Function Quote
ssat2k Posted July 11, 2005 Posted July 11, 2005 Try the above code ....... :-) and pl welcome comment ... Quote
Leaders Iceplug Posted July 11, 2005 Leaders Posted July 11, 2005 Speaking of comments... how about adding some? :p Also, it's not good practice to have your Do Loop loop forever In that case, you could just say Do Loop but, it's also not good to have it exit on the Exit Do. You should integrate the condition that exits the loop into the loop itself. Do Loop Until m_iBytes <= 0 Quote Iceplug, USN One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(
MadMaxx Posted July 14, 2005 Posted July 14, 2005 How do you change is so it writes a KB instead of a byte? Thanks Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.