Usuário com melhor resposta
webclient upload for each pastas e arquivos

Pergunta
-
Por algum motivo desconhecido quando estou fazendo upload dos arquivos via webclient "STOR" que por sinal foi a unica opção que funcionou neste ftp, ele para de fazer download quando passa para a proxima pasta, não da erro nem nada ele só para de fazer upload.
Exemplo...
Essa é a função que percorre as pastas e arquivos na aplicação...
Dim n As New Negocio.Modulo Dim Lista As New List(Of Object) Lista.AddRange(n.Consultar(IdCursoTopico)) contArquivos = 0 contModulos = 0 contTotalModulos = LstLocal.Items.Count contModulos += 1 'Percorre as pastas locais para procurar arquivos .pak For Each item In LstLocal.Items Dim ARQ = (From a In IO.Directory.GetFiles(item.FullNome, "*.pak", SearchOption.AllDirectories) Select New With {.ID = 0, .IdCursoTopico = IDCursoTopico, .XHashFile = Negocio.Hash.TypeHash.SHA1Hash(a) _ , .XHashPath = Negocio.Hash.TypeHash.GetSHA1HashOfPath(a.Substring(1 + a.IndexOf("\" & New FileInfo(a).Directory.Name))) _ , .Path = a.Substring(1 + a.IndexOf("\" & New FileInfo(a).Directory.Name)) _ , .Nome = New FileInfo(a).Name _ , .FullName = a}).ToList contTotalArquivos = ARQ.Count 'Cria o diretorio se não existe no ftp Dim cd As New Negocio.Upload(ARQ(0)) cd.remoteFile = Upload.host & cd.Arquivo.Path.Replace("\", "/") Dim diretorio As String = cd.remoteFile.Replace(cd.remoteFile.Substring(cd.remoteFile.LastIndexOf("/") + 1), "") If Not cd.DirectoryExists(diretorio) Then cd.CreateDirectory(diretorio) End If 'Percorre os arquivos locais e salva no FTP For Each a In ARQ contArquivos += 1 Dim ExisteoArquivo = (From m In Lista Where m.XHashPath = a.XHashPath).ToList If ExisteoArquivo.Count > 0 Then Dim EhoMesmoArquivo = (From m In Lista Where m.XHashFile = a.XHashFile).ToList 'And Select m If EhoMesmoArquivo.Count > 0 Then a.ID = EhoMesmoArquivo.Single.id n.Alterar(a) Dim upLoad As New Negocio.Upload(a) Dim Up As New Processo(AddressOf upLoad.Upload) Dim upAsync As IAsyncResult = Up.BeginInvoke(Nothing, Nothing) While Not upAsync.IsCompleted tbPorcentagem.Text = upLoad.Porcentagem tbPorcentagemTotal.Text = Format(pctArquivos, "0.00") & "%" pbUpload.DataContext = New With {.TotalProcessado = upLoad.totalBytes, .Processados = upLoad.bytesOut} : pbUpload.UpdateLayout() pbUploadTotal.DataContext = New With {.TotalProcessado = contTotalArquivos, .Processados = contArquivos} : pbUploadTotal.UpdateLayout() DoEvent() Thread.Sleep(100) End While End If Else n.Incluir(a) Dim upLoad As New Negocio.Upload(a) Dim Up As New Processo(AddressOf upLoad.Upload) Dim upAsync As IAsyncResult = Up.BeginInvoke(Nothing, Nothing) While Not upAsync.IsCompleted tbPorcentagem.Text = upLoad.Porcentagem tbPorcentagemTotal.Text = Format(pctArquivos, "0.00") & "%" pbUpload.DataContext = New With {.TotalProcessado = upLoad.totalBytes, .Processados = upLoad.bytesOut} : pbUpload.UpdateLayout() pbUploadTotal.DataContext = New With {.TotalProcessado = contTotalArquivos, .Processados = contArquivos} : pbUploadTotal.UpdateLayout() DoEvent() Thread.Sleep(100) End While End If pctArquivos = (contArquivos / contTotalArquivos * 100) Next a contArquivos = 0 pctTotal = (contModulos / contTotalModulos * 100).ToString & "%" Next item MsgBox("Upload de Módulos finalizado com sucesso")
E aqui é o método upload
Public Sub Upload() 'Upload de arquivo por WebClient Dim wcFTP As WebClient wcFTP = New WebClient wcFTP.Credentials = New NetworkCredential("XXXXXXXX", "XXXXXXXX") AddHandler wcFTP.UploadFileCompleted, AddressOf Client_UploadCompleted AddHandler wcFTP.UploadProgressChanged, AddressOf Client_ProgressChanged 'End If Try wcFTP.UploadFileAsync(New Uri(host & Replace(Arquivos.Path, "\", "/")), "STOR", Arquivos.fullname.ToString) 'wcFTP.UploadFile(New Uri(host & Replace(Arquivos.Path, "\", "/")), "STOR", Arquivos.fullname.ToString) While wcFTP.IsBusy DoEvent() End While Catch ex As Exception MsgBox("Erro: " & ex.Message) Finally RemoveHandler wcFTP.UploadFileCompleted, AddressOf Client_UploadCompleted RemoveHandler wcFTP.UploadProgressChanged, AddressOf Client_ProgressChanged GC.Collect() End Try End Sub
Na primeira vez que ele passa pelo primeiro for
For Each item In LstLocal.Items
tudo acontece como o esperado, ele lê a lista de arquivos na pasta, joga na variável ARQ, depois ele percorre a lista ARQ e para cada arquivo ele chama a função upload asyncronamente, toda operação assyncrona é mais para mostrar a atualização do upload em uma progress bar. Porem na segunda vez que ele passa tudo vai normal até ele chamar a função UploadFileAsync(abaixo) do webclient e então a aplicação entra em "looping infinito" porque o webclient não consegue fazer o upload do primeiro arquivo da segunda pasta
wcFTP.UploadFileAsync(New Uri(host & Replace(Arquivos.Path, "\", "/")), "STOR", Arquivos.fullname.ToString) While wcFTP.IsBusy DoEvent() End While
testei, sem as opções assyncronas, e usando o webclient.UploadFile(Uri,"STOR",Filename) também no primeiro arquivo da segunda pasta ele trava e depois da timeout...
Tudo isso serve para atualização dos modulos do curso de uma escola, por exemplo ele tem um curso de excel básico e no curso existem 5 pastas com aquivos, sendo: ExcelB, ExcelB2000, ExcelB2007, ExcelB2010, ExcelB2013, os arquivos dessas pastas são as aulas de cada curso ExcelB1.pak, ExcelB2.pak... ele atualiza a pasta e quando ele vai atualizar a pasta ExcelB2000 no servidor e upar o arquivo ExcelB20001.pak ele fica parado e não atualiza a pasta... já debuguei linha linha e não consegui encontrar nenhum erro, ja testei algumas coisas mas nada muda esta situação.
Desde já obrigado!
Respostas
-
Por algum motivo ainda desconhecido quando chamava pela segunda vez o método para verificar se o diretório existia ou não, nenhum upload funcionava mais ...
Algo esta travando o ftp aqui...
e a solução encontrada foi inserir a linha em negrito
Public Function DirectoryExists(ByVal fileUri As String) As Boolean Dim ftp As WebRequest = WebRequest.Create(fileUri) ftp.Credentials = New NetworkCredential(username, password) ftp.Method = WebRequestMethods.Ftp.ListDirectory Try Dim response As FtpWebResponse = ftp.GetResponse() Catch ex As WebException Dim response As FtpWebResponse = ex.Response If Not (IsNothing(response)) Then If FtpStatusCode.ActionNotTakenFileUnavailable = response.StatusCode Then Return False End If End If End Try ftp.Abort() ftp = Nothing Return True End Function