0

我有从给定位置下载文件然后打开它进行处理的代码。我通过 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
4

1 回答 1

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
于 2013-09-10T17:54:32.187 回答