none
Xamarin - Download de arquivos (FTP) RRS feed

  • Pergunta

  •   Pesquisei aqui no Forum e não encontrei nada que me venha ajudar no meu caso. Eu tenho um método que já usei diversas vezes para fazer download de FTP para Forms e Web, mas no xamarin este método retorna erro.

     Meu caso: Preciso pegar todos os arquivos .mp4 de uma pasta do servidor FTP. Basicamente isto, e quando eu executo o código eu tomo o seguinte erro: Unhandled Exception: System.Net.WebException: An exception occurred during a WebClient request. ocorreu 

     Meu código:

     FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(urlFTP);
                ftpRequest.Credentials = new NetworkCredential(usuario, senha);
                ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
                FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
                StreamReader streamReader = new StreamReader(response.GetResponseStream());
                List<string> diretorios = new List<string>();
    
                string line = streamReader.ReadLine();
                while (!string.IsNullOrEmpty(line))
                {
                    //if (line.Contains(".mp4"))
                    //{
                        diretorios.Add(line);
                        line = streamReader.ReadLine();
                   // }                
                }
                streamReader.Close();
    
                diretorios.RemoveAll(x => !(x.Contains(".mp4")));
    
                using (WebClient ftpClient = new WebClient())
                {
                    ftpClient.Credentials = new System.Net.NetworkCredential(usuario, senha);
    
                    for (int i = 0; i <= diretorios.Count - 1; i++)
                    {
                        if (diretorios[i].Contains("."))
                        {
    
                            string pathRemota =  diretorios[i].ToString();
                            string pathLocal = Path.Combine(urlFTP, diretorios[i].ToString());
    
    
                            var sdCardPath = Android.OS.Environment.DirectoryMovies;
                            // var arquivoPath = System.IO.Path.Combine(sdCardPath, "Video.mp4");
    
                            
                            try
                            {
                                ftpClient.DownloadFile(pathLocal, sdCardPath);
                            }
                            catch (System.Exception)
                            {
    
                                throw;
                            }
                            
                        }
                    }
                }
     Liberei a política de escrita, gerenciamento de arquivos e etc. Fico muito agradecido pelo apoio, realmente estou sofrendo para encontrar uma solução para este "problema".

    sexta-feira, 8 de dezembro de 2017 23:39

Respostas

  • Olá Ares,

    Tomei a liberdade e fiz uma pequena modificação em seu código, espero que agora funcione!

    Fiz no braço isso, pode ser que precise de algum ajuste ainda, rss 🙊

    FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(urlFTP);
    ftpRequest.Credentials = new NetworkCredential(usuario, senha);
    ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
    FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
    StreamReader streamReader = new StreamReader(response.GetResponseStream());
    List<string> diretorios = new List<string>();
    
    string line = streamReader.ReadLine();
    while (!string.IsNullOrEmpty(line))
    {
    	diretorios.Add(line);
    	line = streamReader.ReadLine();            
    }
    streamReader.Close();
    
    diretorios.RemoveAll(x => !(x.Contains(".mp4")));
    
    for (int i = 0; i <= diretorios.Count - 1; i++)
    {
    	if (diretorios[i].Contains("."))
    	{
    		//Certifique que essa variavel: pathRemota
    		//é o diretorio do FTP mais o nome do arquivo
    		string pathRemota =  diretorios[i].ToString();
    		string nomeArquivo = new FileInfo(pathRemota).Name;
    		string pathLocal = Path.Combine(Android.OS.Environment.ExternalStorageDirectory + "/Download", nomeArquivo);
    		
    		var req = (FtpWebRequest)FtpWebRequest.Create(pathRemota);
    		req.Method = WebRequestMethods.Ftp.DownloadFile;
    		req.Credentials = new NetworkCredential(usuario, senha);
    		req.UseBinary = true;
    		req.Proxy = null;
    		
    		try
    		{
    
    			FtpWebResponse response = (FtpWebResponse)req.GetResponse();
    			Stream stream = response.GetResponseStream();
    			byte[] buffer = new byte[2048];
    			FileStream fs = new FileStream(pathLocal, FileMode.Create);
    			int ReadCount = stream.Read(buffer, 0, buffer.Length);
    			while (ReadCount > 0)
    			{
    				fs.Write(buffer, 0, ReadCount);
    				ReadCount = stream.Read(buffer, 0, buffer.Length);
    			}
    			fs.Close();
    			stream.Close();
    		}
    		catch (System.Exception ex)
    		{
    			//Em caso de erro Ares, coloca um brackpoint aqui
    			//e tira um print de todas a propriedades do erro.
    			throw;
    		}
    		
    	}
    }
    


    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    Rafael Almeida
    Senior Developer C#
    Development Leader at JAMSOFT Informática
    Microsoft Certified Professional
    Criador e Mantenedor do EntityFramework Core for Firebird
    Contribuidor do EntityFramework Core
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    quarta-feira, 13 de dezembro de 2017 03:10

Todas as Respostas

  • Olá Ares,

    Você conseguiu resolver isso?

    Eu estava acompanhando algumas coisas no fórum do Xamarin, e me deparei com isso, dê uma olhada ver se ajuda.

    Algumas pessoas enfrentaram problemas relacionados a FTP e conseguiram usando Interface, não fiz o testes para lhe garantir que realmente funciona, em caso de não ser funcional para você post aqui e iremos tentar resolver juntos.

    https://forums.xamarin.com/discussion/90148/upload-image-to-a-ftp-server-using-pcl-xamarin-forms


    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    Rafael Almeida
    Senior Developer C#
    Development Leader at JAMSOFT Informática
    Microsoft Certified Professional
    Criador e Mantenedor do EntityFramework Core for Firebird
    Contribuidor do EntityFramework Core
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter


    domingo, 10 de dezembro de 2017 01:37
  •  Fala Rafael,

     Bom dia!

     Sou novato em xamarin, mas pelo que notei no artigo que passou ele é voltado para xamarin forms. O meu projeto está em Xamarin.Android... No Debug eu consigo pegar todos os arquivos que preciso, porém, quando começo a gravar a informação é que ocorre o erro.

                       if (diretorios[i].Contains("."))
                        {
    
                            string pathRemota = urlFTP + "/" + diretorios[i].ToString();
                            string pathLocal = Path.Combine(urlFTP, diretorios[i].ToString());
                            ftpClient.DownloadFile(pathRemota, dirLocal + "/" + diretorios[i].ToString());
                        }
     Onde ditLocal é = Android.OS.Environment.DirectoryDownloads;

     Será que o caminho está errado? Neste momento estou pensando que é isso...

    segunda-feira, 11 de dezembro de 2017 13:14
  • Olá Ares!

    Você tem certeza que a exception está ocorrendo na chamada do método "DownloadFile"? Caso positivo, já tentou colocar um try/catch nessa operação para ver se não tem uma mensagem de erro mais detalhada (inclusive olhando o valor da InnerException)?

    Abraço!


    André Alves de Lima
    Microsoft MVP - Client App Dev
    Visite o meu site: http://www.andrealveslima.com.br
    Me siga no Twitter: @andrealveslima

    segunda-feira, 11 de dezembro de 2017 13:30
    Moderador
  • Olá Ares,

    Dê uma olhada nessa documentação do Envionment do Xamarin:

    https://developer.xamarin.com/api/type/Android.OS.Environment/

    Se você está conseguindo recuperar as informações, uma possibilidade é a permissão para gravar.

    Olha também isso:

    https://developer.xamarin.com/recipes/ios/network/web_requests/download_a_file/

    cc/ AndreAlvesLima

    Já passou por isso?


    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    Rafael Almeida
    Senior Developer C#
    Development Leader at JAMSOFT Informática
    Microsoft Certified Professional
    Criador e Mantenedor do EntityFramework Core for Firebird
    Contribuidor do EntityFramework Core
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    segunda-feira, 11 de dezembro de 2017 13:37
  • Olá Rafael, não.. Nunca implementei download de FTP no Xamarin.. Mas um try/catch ali ajudaria a entender se o problema está realmente no download e qual a mensagem de erro detalhada (se houver).. :)

    Abs!


    André Alves de Lima
    Microsoft MVP - Client App Dev
    Visite o meu site: http://www.andrealveslima.com.br
    Me siga no Twitter: @andrealveslima

    segunda-feira, 11 de dezembro de 2017 14:20
    Moderador
  • Rafa,

    A documentação é para Xamarin Forms, né? Acho que é diferente do xamarin android.

    Bom, tentei novamente de outra maneira e incluí o try Cath, segue o código:

    if (diretorios[i].Contains("."))
                        {
    
                            string pathRemota = urlFTP + "/" + diretorios[i].ToString();
                            string pathLocal = Path.Combine(Android.OS.Environment.ExternalStorageDirectory + "/Download", diretorios[i].ToString());
                            try
                            {
                                //ftpClient.DownloadFile(pathRemota, filePath + "/" + diretorios[i].ToString());
                                FileStream fs = new FileStream(pathLocal, FileMode.OpenOrCreate);
                            }
                            catch (System.Exception)
                            {
    
                                throw;
                            }
    
                        }

     Ele de certo modo funciona, eu consegui baixar os arquivos... PORÉM.... Vieram em branco como mostra o print:

     

     Espero que isto seja um passo... Mas acho que mostra que a permissão tá ok, pois já fui no Android manifest e dei as permissões de leitura e escrita de arquivos.

     

    segunda-feira, 11 de dezembro de 2017 18:30
  • Olá Ares,

    Esta gravando em "branco" por que você está criando o arquivo vazio manualmente com o FileStream.

    A noite irei fazer uma pequena implementação, e depois lhe mostro como resolvi. Isso se até lã você não tenha conseguido.

    Por enquanto remova o comentário da linha a linha:

    //ftpClient.DownloadFile(pathRemota, filePath + "/" + diretorios[i].ToString());

    e post o erro da exceção. 

    Também coloque o diretório que representa:

    filePath e diretorios[i]


    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    Rafael Almeida
    Senior Developer C#
    Development Leader at JAMSOFT Informática
    Microsoft Certified Professional
    Criador e Mantenedor do EntityFramework Core for Firebird
    Contribuidor do EntityFramework Core
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter


    segunda-feira, 11 de dezembro de 2017 18:39
  • Rafa, valeu pela ajuda! Segue as informações solicitadas...

     As variáveis:

      string storagePath = Android.OS.Environment.ExternalStorageDirectory.Path; // "/storage/emulated/0"
      string filePath = System.IO.Path.Combine(storagePath, diretorios[i].ToString()); // "/storage/emulated/0/sentra.mp4"

    A exceção que acontece é: 

    Unhandled Exception:

    System.Net.WebException: An exception occurred during a WebClient request.

    diretorios[i] é o arquivo MP4 que estou pegando no servidor.


     
    segunda-feira, 11 de dezembro de 2017 19:10
  • Olá Ares!

    Um try com throw direto do jeito que você fez é a mesma coisa que você não adicionar o try/catch.. O que ajudaria a entender o problema real que está acontecendo seria se você logasse a mensagem da exception (completa, inclusive InnerException, caso esteja disponível)..

    Além disso, você já tentou utilizar o conteúdo dessa sua variável "pathLocal" na chamada do método DownloadFile para ver o que acontece?

    Tente substituir o código dessa maneira e veja o que acontece:

    try
    {
    	ftpClient.DownloadFile(pathRemota, pathLocal);
    }
    catch (System.Exception ex)
    {
    	Android.Util.Log.Error("nomedasuaapp", ex.Message);
    	if (ex.InnerException != null)
    	{
    		Android.Util.Log.Error("nomedasuaapp", ex.InnerException.Message);
    	}
    }

    Se os arquivos não forem baixados, dê uma olhada nas mensagens de erro que foram logadas (instruções aqui) e posta aqui pra gente..

    Abraço!


    André Alves de Lima
    Microsoft MVP - Client App Dev
    Visite o meu site: http://www.andrealveslima.com.br
    Me siga no Twitter: @andrealveslima

    terça-feira, 12 de dezembro de 2017 11:44
    Moderador
  • Rafa, valeu pela ajuda! Segue as informações solicitadas...

     As variáveis:

      string storagePath = Android.OS.Environment.ExternalStorageDirectory.Path; // "/storage/emulated/0"
      string filePath = System.IO.Path.Combine(storagePath, diretorios[i].ToString()); // "/storage/emulated/0/sentra.mp4"

    A exceção que acontece é: 

    Unhandled Exception:

    System.Net.WebException: An exception occurred during a WebClient request.

    diretorios[i] é o arquivo MP4 que estou pegando no servidor.


     

    Ares bom dia,

    Não tive como efetuar os testes ontem a noite, precisei resolver algumas coisas pessoais, mais o André está interagindo também, é válido a solicitação dele. se puder fazer o que ele solicitou ajudará tanto ele quanto eu entender melhor.

    Mais se não conseguir acredito que hoje eu tenho como fazer esses testes. (Instalar o Xamarin e simular)


    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    Rafael Almeida
    Senior Developer C#
    Development Leader at JAMSOFT Informática
    Microsoft Certified Professional
    Criador e Mantenedor do EntityFramework Core for Firebird
    Contribuidor do EntityFramework Core
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    terça-feira, 12 de dezembro de 2017 13:14
  •  Prezados, boa tarde!

      No teste acima eu utilizei "Try Catch" e o erro que retornou é: Unhandled Exception:

    System.Net.WebException: An exception occurred during a WebClient request.

     Pessoal,

     Agradeço muito o apoio de todos! Mas se for ocupar muito tempo, não se preocupem! Está sendo um desafio, pois realmente faz muito tempo que não programo, então estou bemmm enferrujado rs... Mas não quero atrapalhar vocês.

     Todavia fico muito grato pelo apoio e pela prestatividade! 


    terça-feira, 12 de dezembro de 2017 16:33
  • Olá Ares,

    Tomei a liberdade e fiz uma pequena modificação em seu código, espero que agora funcione!

    Fiz no braço isso, pode ser que precise de algum ajuste ainda, rss 🙊

    FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(urlFTP);
    ftpRequest.Credentials = new NetworkCredential(usuario, senha);
    ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
    FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
    StreamReader streamReader = new StreamReader(response.GetResponseStream());
    List<string> diretorios = new List<string>();
    
    string line = streamReader.ReadLine();
    while (!string.IsNullOrEmpty(line))
    {
    	diretorios.Add(line);
    	line = streamReader.ReadLine();            
    }
    streamReader.Close();
    
    diretorios.RemoveAll(x => !(x.Contains(".mp4")));
    
    for (int i = 0; i <= diretorios.Count - 1; i++)
    {
    	if (diretorios[i].Contains("."))
    	{
    		//Certifique que essa variavel: pathRemota
    		//é o diretorio do FTP mais o nome do arquivo
    		string pathRemota =  diretorios[i].ToString();
    		string nomeArquivo = new FileInfo(pathRemota).Name;
    		string pathLocal = Path.Combine(Android.OS.Environment.ExternalStorageDirectory + "/Download", nomeArquivo);
    		
    		var req = (FtpWebRequest)FtpWebRequest.Create(pathRemota);
    		req.Method = WebRequestMethods.Ftp.DownloadFile;
    		req.Credentials = new NetworkCredential(usuario, senha);
    		req.UseBinary = true;
    		req.Proxy = null;
    		
    		try
    		{
    
    			FtpWebResponse response = (FtpWebResponse)req.GetResponse();
    			Stream stream = response.GetResponseStream();
    			byte[] buffer = new byte[2048];
    			FileStream fs = new FileStream(pathLocal, FileMode.Create);
    			int ReadCount = stream.Read(buffer, 0, buffer.Length);
    			while (ReadCount > 0)
    			{
    				fs.Write(buffer, 0, ReadCount);
    				ReadCount = stream.Read(buffer, 0, buffer.Length);
    			}
    			fs.Close();
    			stream.Close();
    		}
    		catch (System.Exception ex)
    		{
    			//Em caso de erro Ares, coloca um brackpoint aqui
    			//e tira um print de todas a propriedades do erro.
    			throw;
    		}
    		
    	}
    }
    


    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    Rafael Almeida
    Senior Developer C#
    Development Leader at JAMSOFT Informática
    Microsoft Certified Professional
    Criador e Mantenedor do EntityFramework Core for Firebird
    Contribuidor do EntityFramework Core
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    quarta-feira, 13 de dezembro de 2017 03:10
  • Bom dia,

    Por falta de retorno essa thread está encerrada.

    Se necessário, favor abrir uma nova thread.

    Atenciosamente,

    Filipe B de Castro

    Esse conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita

    MSDN Community Support

    Por favor, lembre-se de Marcar como Resposta as postagens que resolveram o seu problema. Essa é uma maneira comum de reconhecer aqueles que o ajudaram e fazer com que seja mais fácil para os outros visitantes encontrarem a resolução mais tarde.

    segunda-feira, 18 de dezembro de 2017 15:12
    Moderador
  •  Rafael,

     Desculpe a lacuna de tempo! Somente para oficializar a todos, o seu código funcionou! Só alterei este trecho pois a variável já existia... Mas  cara, fico extremamente agradecido pelo seu apoio e sua empatia! Muitissimo obrigado!

    FtpWebResponse response = (FtpWebResponse)req.GetResponse();
    terça-feira, 23 de janeiro de 2018 19:38
  •  Rafael,

     Desculpe a lacuna de tempo! Somente para oficializar a todos, o seu código funcionou! Só alterei este trecho pois a variável já existia... Mas  cara, fico extremamente agradecido pelo seu apoio e sua empatia! Muitissimo obrigado!

    FtpWebResponse response = (FtpWebResponse)req.GetResponse();

    Pow Cara fico feliz! #tamojunto


    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    Rafael Almeida
    Microsoft Developer .NET
    Microsoft Certified Professional
    Development Leader at JAMSOFT Informática
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    terça-feira, 23 de janeiro de 2018 20:05