views:

56

answers:

1

I'm using vb.net 2005, I've got the following code running a thread to download a file. However, the process fails sometimes when trying to read the local copy of the file. I think I may need to unlock the local file somehow but I'm not sure how to do this. Can someone take a look and advise me ?

Dim BP1Ended As Boolean = False
Private Sub BackgroundProcess1()
    BP1Ended = False
    mPadFileStatus = DownloadFile(mstrPadUrl, mLocalFile)
    BP1Ended = True
End Sub

'---'
Dim t As System.Threading.Thread

t = New System.Threading.Thread(AddressOf BackgroundProcess1)
t.Start()

Dim ProcessStartTime As Date = Now()

Do While ProcessStartTime.AddMinutes(1) >= Date.Now 

Application.DoEvents()
If BP1Ended = True Then
    Exit Do
End If
Loop
t.Abort()

PadFileStatus = mPadFileStatus

If BP1Ended = False Then
    Application.DoEvents()
    AddConsoleMsg("Downloading file.... Aborted", True)
End If

'---'
Public Function DownloadFile(ByVal pstrRequestedFile As String, ByVal pstrDestinationFile As String, Optional ByVal TimeOut As Integer = 120) As DownloadStatus
Dim input As IO.Stream
Dim Req As System.Net.HttpWebRequest = Nothing
Dim Response As System.Net.HttpWebResponse

Try
    Req = System.Net.HttpWebRequest.Create(pstrRequestedFile)
Catch ex As Exception                       
    Return DownloadStatus.UnknownError
End Try

Req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"

Req.Timeout = TimeOut * 1000 '120 * 1000 '1 second = 1 000 milliseconds
Try
    Response = Req.GetResponse
    input = Response.GetResponseStream

    Dim streamreader As New StreamReader(input, System.Text.Encoding.GetEncoding("windows-1252")) 'System.Text.Encoding.UTF8)'
    Dim s_response As String = streamreader.ReadToEnd()
    streamreader.Close()

    Dim filestream As New FileStream(pstrDestinationFile, FileMode.Create)
    Dim streamwriter As New StreamWriter(filestream, System.Text.Encoding.GetEncoding("windows-1252")) ' System.Text.Encoding.UTF8)'
    streamwriter.Write(s_response)
    streamwriter.Flush()
    streamwriter.Close()

    Dim length As Long = 1000000 * 100
    Dim pos As Long = 0
    If Response.ContentLength > 0 Then
    length = Response.ContentLength
    End If

    If length > 0 Then
    Return DownloadStatus.OK
    End If

    input.Close()

Catch ew As System.Net.WebException

    If ew.Status = WebExceptionStatus.NameResolutionFailure Or ew.Status = WebExceptionStatus.ProtocolError Then
    Return DownloadStatus.FileNotFound
    ElseIf ew.Status <> WebExceptionStatus.Success Then
    Return DownloadStatus.UnknownError
    End If
    'Dim errorRespone As HttpWebResponse = CType(ew.Response, HttpWebResponse)
    'If errorRespone.StatusCode = HttpStatusCode.NotFound Then '404
    '    Return DownloadStatus.FileNotFound
    'Else
    '    Return DownloadStatus.UnknownError
    'End If'
Catch ex As Exception                                          'Don't know' 

    Return DownloadStatus.UnknownError
End Try

End Function

'---'
Dim OpenFile As FileStream
'OpenFile = New FileStream(pstrPadFile, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)
'FAILS HERE
OpenFile = New FileStream(pstrPadFile, FileMode.Open, FileAccess.Read, FileShare.Read)
+2  A: 

You don't close the file stream in case of exception which might lead to the lock. Make sure you always dispose disposable resources by wrapping them in Using statements:

Using filestream As FileStream = New FileStream(pstrDestinationFile, FileMode.Create)
    Using streamwriter As StreamWriter = New StreamWriter(filestream, Encoding.GetEncoding("windows-1252"))
        streamwriter.Write(s_response)
    End Using
End Using

Same stands true for the response and response streams. They should be properly disposed.

Also you may consider using the WebClient class which has methods like DownloadFile and DownloadData which could make your life much easier.

Darin Dimitrov
OK, cool, so I don't need flush and close after write ?
Jules
No you don't need neither `Flush`, nor `Close`. `Dispose` will do both. And wrapping it in a `Using` statement will guarantee that `Dispose` is called even if an exception is raised.
Darin Dimitrov