Results 1 to 6 of 6

Thread: [RESOLVED] download single file in segment .. error

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2008
    Posts
    382

    Resolved [RESOLVED] download single file in segment .. error

    below is the code for downloading file into segment ..

    vb Code:
    1. Public Class part_down
    2.     Const ChunkSizeConst As Integer = 1024 * 4
    3.    
    4.     Public Delegate Sub _delprogressupdate(ByVal update As String, ByVal row As Integer)
    5.     Public Event progressreport As _delprogressupdate
    6.  
    7.     Public start As Int32
    8.     Public finish As Int32
    9.     Public path As String
    10.     Public url As String
    11.     Public row As Integer
    12.  
    13.  
    14.     Public Sub part_download2()
    15.         Dim req As HttpWebRequest
    16.         Dim resp As Net.HttpWebResponse
    17.  
    18.         req = WebRequest.Create(url)
    19.         req.UserAgent = "NotZilla"
    20.         req.Timeout = -1
    21.         req.AddRange("bytes", start, finish)
    22.  
    23.         resp = req.GetResponse
    24.  
    25.         Dim netstream As IO.Stream = resp.GetResponseStream
    26.         Dim Buffer(ChunkSizeConst - 1) As Byte
    27.         Dim BytesRead As Long
    28.         Dim totalbytesread As Long = 0
    29.  
    30.         Dim file As FileStream
    31.         If start = 0 Then
    32.             file = New FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite)
    33.         Else
    34.             file = New FileStream(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)
    35.         End If
    36.  
    37.  
    38.         Do
    39.             BytesRead = netstream.Read(Buffer, 0, ChunkSizeConst)
    40.             file.Write(Buffer, 0, BytesRead)
    41.             'RaiseEvent writetodisk(Buffer, BytesRead, file)
    42.             totalbytesread += BytesRead
    43.  
    44.             RaiseEvent progressreport((totalbytesread * 100 / resp.ContentLength).ToString("n2") & "%", row)
    45.  
    46.         Loop While BytesRead > 0
    47.     End Sub
    48.  
    49.  
    50. End Class

    in form1
    vb Code:
    1. Private Function DownLoad(ByVal url As String, ByVal path As String)
    2.         'create a request
    3.         Dim req As Net.HttpWebRequest = DirectCast(Net.WebRequest.Create(url), Net.HttpWebRequest)
    4.         req.UserAgent = "NotZilla"
    5.         req.AddRange(0)
    6.         Dim resp As Net.HttpWebResponse = DirectCast(req.GetResponse, Net.HttpWebResponse)
    7.         Dim thr(NumThreads - 1) As Thread
    8.         Dim thrclass(NumThreads - 1) As part_down
    9.         'get a response
    10.         Dim size As Long = resp.ContentLength
    11.         Dim block As Int32 = size \ NumThreads + ChunkSizeConst - ((size \ NumThreads) Mod ChunkSizeConst)
    12.         'Dim support_multi As Boolean = False
    13.         'get its stream
    14.         'Dim BufString As New System.Text.StringBuilder()
    15.         Dim i As Integer
    16.         For i = 0 To NumThreads - 1
    17.             thrclass(i) = New part_down()
    18.             thrclass(i).url = url
    19.             thrclass(i).path = path.Replace(IO.Path.GetFileNameWithoutExtension(path), IO.Path.GetFileNameWithoutExtension(path) & i.ToString)
    20.             thrclass(i).row = i
    21.  
    22.             AddHandler thrclass(i).progressreport, AddressOf statusupdate
    23.         Next
    24.         thrclass(0).start = 0
    25.         thrclass(0).finish = block - 1
    26.  
    27.         If resp.StatusCode = Net.HttpStatusCode.PartialContent Then
    28.             '   support_multi = True
    29.             For i = 0 To NumThreads - 1
    30.                 thr(i) = New Thread(AddressOf thrclass(i).part_download)
    31.                 thr(i).Start()
    32.                 addnewitemto_listview(SetBytes(thrclass(i).finish - thrclass(i).start))
    33.  
    34.                 'part_download()
    35.                 If i < NumThreads - 1 Then
    36.                     thrclass(i + 1).start = thrclass(i).finish
    37.                     If i = NumThreads - 2 Then
    38.                         thrclass(i + 1).finish = size
    39.                     Else
    40.                         thrclass(i + 1).finish = thrclass(i).finish + block - 1
    41.                         'thrclass(i + 1).finish += block - 1
    42.                     End If
    43.                 End If
    44.             Next
    45.             For i = 0 To NumThreads - 1
    46.                 thr(i).Join()
    47.             Next
    48.             MsgBox("Completed")
    49.         End If
    50.     End Function

    after that i Applied binary joining suggested by stanav


    Quote Originally Posted by stanav View Post
    Try something like this:
    Code:
     Private Sub JoinFiles(ByVal fileChunks As List(Of String), ByVal output As String, Optional ByVal deleteFileChunksWhenDone As Boolean = False)
            Try
                Using outStream As New IO.FileStream(output, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None)
                    Using writer As New IO.BinaryWriter(outStream)
                        For i As Integer = 0 To fileChunks.Count - 1
                            Using inStream As New IO.FileStream(fileChunks(i), System.IO.FileMode.Open)
                                Using reader As New IO.BinaryReader(inStream)
                                    writer.Write(reader.ReadBytes(reader.BaseStream.Length))
                                End Using
                            End Using
                        Next
                    End Using
                End Using
                If deleteFileChunksWhenDone = True Then
                    For Each chunk As String In fileChunks
                        IO.File.Delete(chunk)
                    Next
                End If
            Catch ex As Exception
                MessageBox.Show(ex.Message())
            End Try
        End Sub
    Usage example:
    Code:
    'Create a list of files to be joined. The files are added to the list in the order to be joined.
    Dim files2Join As New List(Of String)
    files2Join.Add("C:\test\New Folder\New Folder\hehe1.flv")
    files2Join.Add("C:\test\New Folder\New Folder\hehe2.flv")
    files2Join.Add("C:\test\New Folder\New Folder\hehe3.flv")
    
    'Set a path for the joined output file
    Dim outputFile As String = "C:\test\New Folder\New Folder\hehe.flv"
    
    'Join the files and delete the original files when done.
    JoinFiles(files2Join, outputFile, True)

    But after joinng output was not right

    dunno what's wrong

    thanks
    Last edited by CatchItBaby; Jul 20th, 2012 at 10:03 AM.

  2. #2
    PowerPoster stanav's Avatar
    Join Date
    Jul 2006
    Location
    Providence, RI - USA
    Posts
    9,289

    Re: download single file in segment .. error

    I believe this part in the part_download2 method is what causes the corruption of the file after joining:
    Code:
     Dim file As FileStream
            If start = 0 Then
                file = New FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite)
            Else
                file = New FileStream(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)
            End If
    Besides, the whole thing is very poorly written...
    Please try this code I just wrote. Since I'm at work right now I our firewall blocks all video sites, I can't test download a video file. However, I downloaded a few zip files using it and it seems to work correctly.
    Anyway, if you found a bug in my code, please report back and I'm more than happy to try to help you fix it (when I can, of course )
    This is the Download class
    vb Code:
    1. Imports System.Net
    2. Imports System.IO
    3.  
    4. Public Class Download
    5.     Const ChunkSize As Integer = 1024 * 4
    6.     Public StartPosition As Long = 0
    7.     Public DownloadLength As Long = 0
    8.     Public FilePath As String = String.Empty
    9.     Public DownloadUrl As String = String.Empty
    10.     Public Name As String = String.Empty
    11.     Public DownloadResponse As HttpWebResponse = Nothing
    12.     Public DownloadStream As IO.Stream = Nothing
    13.     Public IsComplete As Boolean = False
    14.  
    15.     Public Delegate Sub _delprogressupdate(ByVal sender As Object, ByVal e As Download.DownloadProgress)
    16.     Public Event ProgressReport As _delprogressupdate
    17.  
    18.     Public Delegate Sub _deldownloadcompleted(ByVal sender As Object, ByVal e As Download.DownloadProgress)
    19.     Public Event DownloadCompleted As _deldownloadcompleted
    20.  
    21.     Public Sub DownloadChunk()
    22.         If Not String.IsNullOrEmpty(DownloadUrl) Then
    23.             Dim req As HttpWebRequest = Net.HttpWebRequest.Create(DownloadUrl)
    24.             With req
    25.                 .UserAgent = "NotZilla"
    26.                 req.Timeout = -1
    27.                 req.AddRange("bytes", StartPosition, StartPosition + DownloadLength)
    28.             End With
    29.             DownloadResponse = req.GetResponse()
    30.             DownloadStream = DownloadResponse.GetResponseStream()
    31.             DownloadIt()
    32.         End If
    33.     End Sub
    34.  
    35.     Public Sub DownloadIt()
    36.         Dim buffer(ChunkSize - 1) As Byte
    37.         Dim bytesRead As Long = 0
    38.         Dim totalBytesRead As Long = 0
    39.         Dim stopFlag As Boolean = False
    40.         Using fs As New IO.FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None)
    41.             Do
    42.                 bytesRead = DownloadStream.Read(buffer, 0, ChunkSize)
    43.                 fs.Write(buffer, 0, bytesRead)
    44.                 totalBytesRead += bytesRead
    45.                 RaiseEvent ProgressReport(Me, New DownloadProgress(Me.FilePath, totalBytesRead, DownloadLength - totalBytesRead))
    46.             Loop While totalBytesRead < DownloadLength
    47.         End Using
    48.         DownloadStream.Close()
    49.         DownloadResponse.Close()
    50.         Me.IsComplete = True
    51.         RaiseEvent DownloadCompleted(Me, New DownloadProgress(Me.FilePath, totalBytesRead, DownloadLength - totalBytesRead))
    52.     End Sub
    53.  
    54.     Public Class DownloadProgress
    55.         Private _filePath As String
    56.         Private _bytesDownloaded As Long
    57.         Private _bytesRemain As Long
    58.         Private _percentCompleted As Double
    59.  
    60.         Public ReadOnly Property FilePath() As String
    61.             Get
    62.                 Return _filePath
    63.             End Get
    64.         End Property
    65.  
    66.         Public ReadOnly Property BytesDownloaded() As Long
    67.             Get
    68.                 Return _bytesDownloaded
    69.             End Get
    70.         End Property
    71.  
    72.         Public ReadOnly Property BytesRemaining() As Long
    73.             Get
    74.                 Return _bytesRemain
    75.             End Get
    76.         End Property
    77.  
    78.         Public ReadOnly Property PercentCompleted() As Double
    79.             Get
    80.                 Return _percentCompleted
    81.             End Get
    82.         End Property
    83.  
    84.         Public Sub New(ByVal path As String, ByVal bytesRead As Long, ByVal bytesRemaining As Long)
    85.             _filePath = path
    86.             _bytesDownloaded = bytesRead
    87.             _bytesRemain = bytesRemaining
    88.             _percentCompleted = bytesRead * 100 / (bytesRead + bytesRemaining)
    89.         End Sub
    90.     End Class
    91.  
    92. End Class
    And usage implementation. You can paste the whole thing in your form's code
    vb Code:
    1. Private downloadList As New List(Of Download)
    2.  
    3.     Private Sub DoParallelDownload(ByVal url As String, ByVal saveTo As String)
    4.         Me.downloadList.Clear()
    5.         'We 1st need to find out how big the file is and whether the download can be split
    6.         Dim req As Net.HttpWebRequest = Net.HttpWebRequest.Create(url)
    7.         req.UserAgent = "NotZilla"
    8.         req.AddRange(0)
    9.         Dim resp As Net.HttpWebResponse = req.GetResponse()
    10.         Dim downloadSize As Long = resp.ContentLength
    11.         Dim netStream As IO.Stream = resp.GetResponseStream()
    12.         If resp.StatusCode = Net.HttpStatusCode.PartialContent Then
    13.             'Yes, we can split this download
    14.             Dim numberOfThreads As Integer = 5
    15.             Dim aDownload As Download = Nothing
    16.             Dim thrds(numberOfThreads - 1) As Threading.Thread
    17.             Dim thdStart As Threading.ThreadStart = Nothing
    18.             Dim downloadLength As Long = downloadSize \ numberOfThreads
    19.             For i As Integer = 0 To numberOfThreads - 1
    20.                 aDownload = New Download()
    21.                 aDownload.DownloadUrl = url
    22.                 aDownload.FilePath = saveTo & ".dlpart" & i.ToString("000")
    23.                 aDownload.StartPosition = i * downloadLength
    24.                 aDownload.DownloadLength = downloadLength
    25.                 aDownload.Name = IO.Path.GetFileName(aDownload.FilePath)
    26.                 If i = numberOfThreads - 1 Then
    27.                     aDownload.DownloadLength += downloadSize Mod numberOfThreads
    28.                 End If
    29.                 AddHandler aDownload.ProgressReport, AddressOf Download_ProgressReport
    30.                 AddHandler aDownload.DownloadCompleted, AddressOf Download_Completed
    31.                 If i = 0 Then
    32.                     aDownload.DownloadResponse = resp
    33.                     aDownload.DownloadStream = netStream
    34.                     thdStart = New Threading.ThreadStart(AddressOf aDownload.DownloadIt)
    35.                 Else
    36.                     thdStart = New Threading.ThreadStart(AddressOf aDownload.DownloadChunk)
    37.                 End If
    38.                 thrds(i) = New Threading.Thread(thdStart)
    39.                 thrds(i).Start()
    40.                 Me.downloadList.Add(aDownload)
    41.             Next
    42.         Else
    43.             'No, we can't split this download so we have to download it using 1 thread.
    44.             Dim dl As New Download()
    45.             dl.DownloadUrl = url
    46.             dl.FilePath = saveTo
    47.             dl.StartPosition = 0
    48.             dl.DownloadLength = downloadSize
    49.             dl.Name = IO.Path.GetFileName(dl.FilePath)
    50.             dl.DownloadResponse = resp
    51.             dl.DownloadStream = netStream
    52.             AddHandler dl.ProgressReport, AddressOf Download_ProgressReport
    53.             AddHandler dl.DownloadCompleted, AddressOf Download_Completed
    54.             Dim thdStart As New Threading.ThreadStart(AddressOf dl.DownloadIt)
    55.             Dim thd As New Threading.Thread(thdStart)
    56.             thd.Start()
    57.             Me.downloadList.Add(dl)
    58.         End If
    59.     End Sub
    60.  
    61.     Private Sub Download_ProgressReport(ByVal sender As Object, ByVal e As Download.DownloadProgress)
    62.         'Your own code to report progress here. This progress report is for 1 chunk. If you want the overall progress, you'll have to calculate it yourself.
    63.         Dim progress As String = String.Format("Download status for file {0}{4}BytesDownloaded: {1}{4}BytesRemaining: {2}{4}PercentCompleted: {3}{4}", _
    64.                                                 IO.Path.GetFileName(e.FilePath), e.BytesDownloaded, e.BytesRemaining, e.PercentCompleted, Environment.NewLine)
    65.         Debug.Write(progress)
    66.     End Sub
    67.  
    68.     Private Sub Download_Completed(ByVal sender As Object, ByVal e As Download.DownloadProgress)
    69.         Dim filePath As String = e.FilePath
    70.         Dim doneCount As Integer = 0
    71.         Dim fileList As New List(Of String)
    72.         For Each item As Download In Me.downloadList
    73.             If item.FilePath = filePath Then
    74.                 item.IsComplete = True
    75.             End If
    76.             If item.IsComplete = True Then
    77.                 doneCount += 1
    78.             End If
    79.             fileList.Add(item.FilePath)
    80.         Next
    81.         If doneCount = Me.downloadList.Count Then
    82.             If doneCount = 1 Then
    83.                 'This file was downloaded in whole. No need to do the joining.
    84.             Else
    85.                 'All file chunks are downloaded. Start joining them using the DownloadList to get the file paths of those chunks
    86.                 fileList.Sort()
    87.                 Dim folder As String = IO.Path.GetDirectoryName(filePath)
    88.                 Dim fileName As String = IO.Path.GetFileNameWithoutExtension(filePath)
    89.                 Me.JoinFiles(fileList, IO.Path.Combine(folder, fileName), True)
    90.                 Debug.WriteLine("Done joining files")
    91.             End If
    92.         End If
    93.     End Sub
    94.  
    95.     Private Sub JoinFiles(ByVal fileChunks As List(Of String), ByVal output As String, Optional ByVal deleteFileChunksWhenDone As Boolean = False)
    96.         Try
    97.             Using outStream As New IO.FileStream(output, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None)
    98.                 Using writer As New IO.BinaryWriter(outStream)
    99.                     For i As Integer = 0 To fileChunks.Count - 1
    100.                         Using inStream As New IO.FileStream(fileChunks(i), System.IO.FileMode.Open)
    101.                             Using reader As New IO.BinaryReader(inStream)
    102.                                 writer.Write(reader.ReadBytes(reader.BaseStream.Length))
    103.                             End Using
    104.                         End Using
    105.                     Next
    106.                 End Using
    107.             End Using
    108.             If deleteFileChunksWhenDone = True Then
    109.                 For Each chunk As String In fileChunks
    110.                     IO.File.Delete(chunk)
    111.                 Next
    112.             End If
    113.         Catch ex As Exception
    114.             MessageBox.Show(ex.Message())
    115.         End Try
    116.     End Sub

    And finally, usage example:
    Code:
    'In a button click or something similar, you do:
     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim url As String = "the url to the file to be downloaded here"
            Dim savePath As String = "the full path to where it should be saved after done done loading here"
            Me.DoParallelDownload(url, savePath)
           
        End Sub
    Enjoy
    Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
    - Abraham Lincoln -

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2008
    Posts
    382

    Re: download single file in segment .. error

    having same problem

    - after joining video file was not playing (or stopped in middle .. played via vlc media player)

    - and i tried one rar archive and after completition when i opened rar file it shows unexpected end or archive error

  4. #4
    PowerPoster stanav's Avatar
    Join Date
    Jul 2006
    Location
    Providence, RI - USA
    Posts
    9,289

    Re: download single file in segment .. error

    You you have a download url that I can use to test?
    Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
    - Abraham Lincoln -

  5. #5
    PowerPoster stanav's Avatar
    Join Date
    Jul 2006
    Location
    Providence, RI - USA
    Posts
    9,289

    Re: download single file in segment .. error

    OK... I think I found where the bug was and corrected it. Although I haven't tested downloading a .rar or video file, but it looks good with zip files. The MD5 hash of the downloaded file matches that of the original file.
    And here is the revised code:
    vb Code:
    1. Imports System.Net
    2. Imports System.IO
    3.  
    4. Public Class Download
    5.     Const ChunkSize As Integer = 1024 * 4
    6.     Public StartPosition As Long = 0
    7.     Public DownloadLength As Long = 0
    8.     Public FilePath As String = String.Empty
    9.     Public DownloadUrl As String = String.Empty
    10.     Public Name As String = String.Empty
    11.     Public DownloadResponse As HttpWebResponse = Nothing
    12.     Public DownloadStream As IO.Stream = Nothing
    13.     Public IsComplete As Boolean = False
    14.  
    15.     Public Delegate Sub _delprogressupdate(ByVal sender As Object, ByVal e As Download.DownloadProgress)
    16.     Public Event ProgressReport As _delprogressupdate
    17.  
    18.     Public Delegate Sub _deldownloadcompleted(ByVal sender As Object, ByVal e As Download.DownloadProgress)
    19.     Public Event DownloadCompleted As _deldownloadcompleted
    20.  
    21.     Public Sub DownloadChunk()
    22.         If Not String.IsNullOrEmpty(DownloadUrl) Then
    23.             Dim req As HttpWebRequest = Net.HttpWebRequest.Create(DownloadUrl)
    24.             With req
    25.                 .UserAgent = "NotZilla"
    26.                 req.Timeout = -1
    27.                 req.AddRange("bytes", StartPosition, StartPosition + DownloadLength)
    28.             End With
    29.             DownloadResponse = req.GetResponse()
    30.             DownloadStream = DownloadResponse.GetResponseStream()
    31.             DownloadIt()
    32.         End If
    33.     End Sub
    34.  
    35.     Public Sub DownloadIt()
    36.         Dim buffer(ChunkSize - 1) As Byte
    37.         Dim bytes2Download As Long = ChunkSize
    38.         Dim bytesRemain As Long = DownloadLength
    39.         Dim bytesRead As Long = 0
    40.         Dim totalBytesRead As Long = 0
    41.         Using fs As New IO.FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None)
    42.             Do
    43.                 bytesRemain = DownloadLength - totalBytesRead
    44.                 If bytesRemain < ChunkSize Then
    45.                     bytes2Download = bytesRemain
    46.                 End If
    47.                 bytesRead = DownloadStream.Read(buffer, 0, bytes2Download)
    48.                 fs.Write(buffer, 0, bytesRead)
    49.                 totalBytesRead += bytesRead
    50.                 RaiseEvent ProgressReport(Me, New DownloadProgress(Me.FilePath, totalBytesRead, DownloadLength - totalBytesRead))
    51.             Loop While totalBytesRead < DownloadLength
    52.         End Using
    53.         DownloadStream.Close()
    54.         DownloadResponse.Close()
    55.         Me.IsComplete = True
    56.         RaiseEvent DownloadCompleted(Me, New DownloadProgress(Me.FilePath, totalBytesRead, DownloadLength - totalBytesRead))
    57.     End Sub
    58.  
    59.     Public Class DownloadProgress
    60.         Private _filePath As String
    61.         Private _bytesDownloaded As Long
    62.         Private _bytesRemain As Long
    63.         Private _percentCompleted As Double
    64.  
    65.         Public ReadOnly Property FilePath() As String
    66.             Get
    67.                 Return _filePath
    68.             End Get
    69.         End Property
    70.  
    71.         Public ReadOnly Property BytesDownloaded() As Long
    72.             Get
    73.                 Return _bytesDownloaded
    74.             End Get
    75.         End Property
    76.  
    77.         Public ReadOnly Property BytesRemaining() As Long
    78.             Get
    79.                 Return _bytesRemain
    80.             End Get
    81.         End Property
    82.  
    83.         Public ReadOnly Property PercentCompleted() As Double
    84.             Get
    85.                 Return _percentCompleted
    86.             End Get
    87.         End Property
    88.  
    89.         Public Sub New(ByVal path As String, ByVal bytesRead As Long, ByVal bytesRemaining As Long)
    90.             _filePath = path
    91.             _bytesDownloaded = bytesRead
    92.             _bytesRemain = bytesRemaining
    93.             _percentCompleted = bytesRead * 100 / (bytesRead + bytesRemaining)
    94.         End Sub
    95.     End Class
    96.  
    97. End Class
    And the implementation code (some changes were made in the thread creating loop and the joinfiles sub)
    vb Code:
    1. Private downloadList As New List(Of Download)
    2.  
    3.     Private Sub DoParallelDownload(ByVal url As String, ByVal saveTo As String)
    4.         Me.downloadList.Clear()
    5.         'We 1st need to find out how big the file is and whether the download can be split
    6.         Dim req As Net.HttpWebRequest = Net.HttpWebRequest.Create(url)
    7.         req.UserAgent = "NotZilla"
    8.         req.AddRange(0)
    9.         Dim resp As Net.HttpWebResponse = req.GetResponse()
    10.         Dim downloadSize As Long = resp.ContentLength
    11.         Dim netStream As IO.Stream = resp.GetResponseStream()
    12.         If resp.StatusCode = Net.HttpStatusCode.PartialContent Then
    13.             'Yes, we can split this download
    14.             Dim numberOfThreads As Integer = 5
    15.             Dim aDownload As Download = Nothing
    16.             Dim thrds(numberOfThreads - 1) As Threading.Thread
    17.             Dim thdStart As Threading.ThreadStart = Nothing
    18.             Dim downloadLength As Long = downloadSize \ numberOfThreads
    19.             For i As Integer = 0 To numberOfThreads - 1
    20.                 aDownload = New Download()
    21.                 aDownload.DownloadUrl = url
    22.                 aDownload.FilePath = saveTo & "." & (i + 1).ToString("000")
    23.                 aDownload.StartPosition = i * downloadLength
    24.                 aDownload.DownloadLength = downloadLength
    25.                 aDownload.Name = IO.Path.GetFileName(aDownload.FilePath)
    26.                 If i = numberOfThreads - 1 Then
    27.                     aDownload.DownloadLength += downloadSize Mod numberOfThreads
    28.                 End If
    29.                 AddHandler aDownload.ProgressReport, AddressOf Download_ProgressReport
    30.                 AddHandler aDownload.DownloadCompleted, AddressOf Download_Completed
    31.                 If i = 0 Then
    32.                     aDownload.DownloadResponse = resp
    33.                     aDownload.DownloadStream = netStream
    34.                     thdStart = New Threading.ThreadStart(AddressOf aDownload.DownloadIt)
    35.                 Else
    36.                     thdStart = New Threading.ThreadStart(AddressOf aDownload.DownloadChunk)
    37.                 End If
    38.                 thrds(i) = New Threading.Thread(thdStart)
    39.                 thrds(i).Start()
    40.                 Me.downloadList.Add(aDownload)
    41.             Next
    42.         Else
    43.             'No, we can't split this download so we have to download it using 1 thread.
    44.             Dim dl As New Download()
    45.             dl.DownloadUrl = url
    46.             dl.FilePath = saveTo
    47.             dl.StartPosition = 0
    48.             dl.DownloadLength = downloadSize
    49.             dl.Name = IO.Path.GetFileName(dl.FilePath)
    50.             dl.DownloadResponse = resp
    51.             dl.DownloadStream = netStream
    52.             AddHandler dl.ProgressReport, AddressOf Download_ProgressReport
    53.             AddHandler dl.DownloadCompleted, AddressOf Download_Completed
    54.             Dim thdStart As New Threading.ThreadStart(AddressOf dl.DownloadIt)
    55.             Dim thd As New Threading.Thread(thdStart)
    56.             thd.Start()
    57.             Me.downloadList.Add(dl)
    58.         End If
    59.     End Sub
    60.  
    61.     Private Sub Download_ProgressReport(ByVal sender As Object, ByVal e As Download.DownloadProgress)
    62.         'Your own code to report progress here. This progress report is for 1 chunk. If you want the overall progress, you'll have to calculate it yourself.
    63.         Dim progress As String = String.Format("Download status for file {0}{4}BytesDownloaded: {1}{4}BytesRemaining: {2}{4}PercentCompleted: {3}{4}", _
    64.                                                 IO.Path.GetFileName(e.FilePath), e.BytesDownloaded, e.BytesRemaining, e.PercentCompleted, Environment.NewLine)
    65.         Debug.Write(progress)
    66.     End Sub
    67.  
    68.     Private Sub Download_Completed(ByVal sender As Object, ByVal e As Download.DownloadProgress)
    69.         Dim filePath As String = e.FilePath
    70.         Dim doneCount As Integer = 0
    71.         Dim fileList As New List(Of String)
    72.         For Each item As Download In Me.downloadList
    73.             If item.FilePath = filePath Then
    74.                 item.IsComplete = True
    75.             End If
    76.             If item.IsComplete = True Then
    77.                 doneCount += 1
    78.             End If
    79.             fileList.Add(item.FilePath)
    80.         Next
    81.         If doneCount = Me.downloadList.Count Then
    82.             If doneCount = 1 Then
    83.                 'This file was downloaded in whole. No need to do the joining.
    84.             Else
    85.                 'All file chunks are downloaded. Start joining them using the DownloadList to get the file paths of those chunks
    86.                 fileList.Sort()
    87.                 Dim folder As String = IO.Path.GetDirectoryName(filePath)
    88.                 Dim fileName As String = IO.Path.GetFileNameWithoutExtension(filePath)
    89.                 Me.JoinFiles(fileList, IO.Path.Combine(folder, fileName), False)
    90.                 Debug.WriteLine("Done joining files")
    91.             End If
    92.         End If
    93.     End Sub
    94.  
    95.     Private Sub JoinFiles(ByVal fileChunks As List(Of String), ByVal output As String, Optional ByVal deleteFileChunksWhenDone As Boolean = False)
    96.         Try
    97.             Using outStream As New IO.FileStream(output, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None)
    98.                 For i As Integer = 0 To fileChunks.Count - 1
    99.                     Using inStream As New IO.FileStream(fileChunks(i), System.IO.FileMode.Open)
    100.                         Dim buffer(inStream.Length - 1) As Byte
    101.                         inStream.Read(buffer, 0, buffer.Length)
    102.                         outStream.Write(buffer, 0, buffer.Length)
    103.                     End Using
    104.                 Next
    105.             End Using
    106.             If deleteFileChunksWhenDone = True Then
    107.                 For Each chunk As String In fileChunks
    108.                     IO.File.Delete(chunk)
    109.                 Next
    110.             End If
    111.         Catch ex As Exception
    112.             MessageBox.Show(ex.Message())
    113.         End Try
    114.     End Sub

    Please try again with this new code and give any feedback you have.
    Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
    - Abraham Lincoln -

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2008
    Posts
    382

    Re: [RESOLVED] download single file in segment .. error

    Thanks working fine now

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width