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