下载后使用FtpWebRequest锁定文件

时间:2013-09-10 17:00:19

标签: vb.net ftp

我有代码从给定位置下载文件,然后打开它进行处理。我通过FtpWebRequest和FtpWebResponse对象在FTP上执行此操作,将响应读入StreamReader,然后通过StreamWriter将该流写入文件。

我遇到的问题是,当我稍后将文件加载到StreamReader中时,我得到一个异常,说我的文件正由另一个进程使用。有趣的是,如果文件不在那里下载的情况下不会发生这种情况,尽管在这种情况下我也没有例外。

以下是相关的代码部分:

Try
            Dim ftpResponse As FtpWebResponse = DirectCast(ftpRequest.GetResponse(), FtpWebResponse)
            stream = ftpResponse.GetResponseStream()
            reader = New StreamReader(stream, Encoding.UTF8)

            Dim destinationFile As String = _workingDirectory + _filename
            writer = New StreamWriter(destinationFile, False)
            writer.Write(reader.ReadToEnd())

            result = True
        Catch ex As Exception
            EventLog.LogEvent("UpdateInventory", String.Format("Unable to download file: {0}. <br/ > {1}", downloadUri, ex.ToString()), BVSoftware.BVC5.Core.Metrics.EventLogSeverity.Error)
        Finally
            If stream IsNot Nothing Then
                stream.Close()
            End If

            If reader IsNot Nothing Then
                reader.Close()
            End If

            If writer IsNot Nothing Then
                writer.Close()
            End If
        End Try

1 个答案:

答案 0 :(得分:0)

在关闭之前尝试调用writer.flush。它将任何缓冲的数据写入底层流。 以下是我实现它的方式(http://dot-net-talk.blogspot.in/2008/12/how-to-create-ftp-client-in-vbnet.html):

Public Function Download(ByVal sourceFilename As String, ByVal targetFI As FileInfo, Optional ByVal PermitOverwrite As Boolean = False) As Boolean
    '1. check target
    If targetFI.Exists And Not (PermitOverwrite) Then
        'Throw New ApplicationException("Target file already exists")
        RaiseEvent StatusChanged("Target file already exists")
    End If
    '2. check source
    Dim URI As String = GetCurrentUrl() & "/" & sourceFilename
    '3. perform copy
    Dim ftp As Net.FtpWebRequest = GetRequest(URI)
    'Set request to download a file in binary mode
    ftp.Method = Net.WebRequestMethods.Ftp.DownloadFile
    ftp.UseBinary = True
    'open request and get response stream
    Using response As FtpWebResponse = CType(ftp.GetResponse, FtpWebResponse)
        Using responseStream As Stream = response.GetResponseStream
            'loop to read & write to file
            Using fs As FileStream = targetFI.OpenWrite
                Try
                    Dim buffer(2047) As Byte
                    Dim read As Integer = 0
                    Do
                        read = responseStream.Read(buffer, 0, buffer.Length)
                        fs.Write(buffer, 0, read)
                    Loop Until read = 0
                    responseStream.Close()
                    fs.Flush()
                    fs.Close()
                Catch ex As Exception
                    'catch error and delete file only partially downloaded
                    fs.Close()
                    'delete target file as it's incomplete
                    targetFI.Delete()
                    'Throw
                    RaiseEvent StatusChanged("Download was incomplete due to an error...")
                End Try
            End Using
            responseStream.Close()
        End Using
        response.Close()
    End Using
    Return True
End Function