Закачиваю файл на FTP-сервер, где другая программа его должна забрать

Владимир Саныч

Мое почтение всем и благодарность заранее.Закачиваю файл на FTP-сервер. Один нюанс: на сервере бежит некая программа (не моя), которая ждет моего файла и при его получении моментально его перемещает в другое место (недоступное для меня). Собственно, взаимодействие с этой программой (создание файла для нее) и есть моя задача.Вот код, который я нашел в Интернете (в этом форуме тоже видел ссылку на нечто похожее) и слегка причесал под свои нужды:
Net.ServicePointManager.ServerCertificateValidationCallback = AddressOf validateCert
 Dim sAdd As String = IIf(sAction = "NLST", "", "/" & sFile)
 Dim request As FtpWebRequest = DirectCast(WebRequest.Create(msFtpServer & sAdd), FtpWebRequest)
 request.Method = sAction
 request.EnableSsl = True
 request.Credentials = oNc
 Select Case sAction
 Case "RENAME"
 request.RenameTo = sNewName
 request.KeepAlive = False
 request.GetResponse.Close()
 Exit Sub
 End Select
 Dim response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)
 Select Case sAction
 Case "NLST"
 Dim reader As New StreamReader(response.GetResponseStream())
 Dim str As String = reader.ReadLine
 cFiles = New Collection
 Do Until str Is Nothing
 Try
 cFiles.Add(str, str)
 Catch ex As Exception
 End Try
 str = reader.ReadLine
 Loop
 reader.Close()
 Case "STOR"
 Dim oFile As FileInfo = New FileInfo(msTmpStorage & "\" & sFile)
 Dim fileContents(oFile.Length) As Byte
 Using fr As FileStream = oFile.OpenRead
 fr.Read(fileContents, 0, Convert.ToInt32(oFile.Length))
 End Using
 Using writer As Stream = request.GetRequestStream
 writer.Write(fileContents, 0, fileContents.Length)
 End Using
 Case "RETR"
 Dim responseStream As Stream = response.GetResponseStream
 Dim fs As New FileStream(msTmpStorage & "\" & sFile, FileMode.Create)
 Dim buffer(2047) As Byte
 Dim read As Integer = 1
 Do While read <> 0
 read = responseStream.Read(buffer, 0, buffer.Length)
 fs.Write(buffer, 0, read)
 Loop
 fs.Flush()
 fs.Close()
 responseStream.Close()
 End Select
 response.Close()
Пытаюсь обращаться к этому коду двумя способами, в обоих случаях возникает проблема. А именно:Способ 1. Просто запускаю с параметром sAction="STOR". В тот момент, когда у меня исполняется строка Dim response, на сервере уже появляется файл (пока нулевого размера). Та программа его сразу забирает, не дожидаясь, пока он создастся полностью. Потом она его забирает еще раз, но это создает им проблемы.Способ 2. Запускаю сначала с параметром sAction="STOR", но с другим именем файла, а потом с параметром sAction="RENAME". Тогда на файле остается какая-то блокировка, из-за которой та программа не может его забрать. При этом я сам руками могу этот файл перемещать и удалять без проблем.Что мне изменить, чтобы оно заработало - хоть по первому способу, хоть по второму?
3 ответа

Владимир Саныч

P.S. В приведенном отрывке используются некоторые мои переменные, которых я не пояснил. Надеюсь, что их смысл понятен.


Владимир Саныч

Раз никто не отвечает, доложу о результатах сам.Перенес строчку Dim response в конец кода, всё заработало. Возможно, это вообще лишняя переменная и ее не надо открывать и закрывать, это я не проверял. Не проверял я и способ 2 с ренеймом, только предполагаю, что можно попробовать расщепить команду request.GetResponse.Close() на две, как в остальных случаях (одной командой Dim response, а второй Close).Однако теперь мне напомнили про другую проблему. Этот код
Using fr As FileStream = oFile.OpenRead
 fr.Read(fileContents, 0, Convert.ToInt32(oFile.Length))
 End Using
 Using writer As Stream = request.GetRequestStream
 writer.Write(fileContents, 0, fileContents.Length)
 End Using
создает файл на один байт длиннее, чем надо. В конце добавляется какой-то лишний символ. Догадываюсь, что дело в 0, fileContents.Length, буду экспериментировать, но если кто-то точно знает, как надо исправить, то буду благодарен.


Владимир Саныч

Догадываюсь, что дело в 0, fileContents.Length
Догадка была верна. Исправил на 0, fileContents.Length - 1, проблема исчезла.Теперь если у кого-то возникнут похожие вопросы, то в этом форуме будет топик на эту тему.