Scaricare file da ftp

venerdì 11 luglio 2008 - 11.25

toyo86 Profilo | Junior Member

ciao a tutti, spero di essere nella sezione giusta..ho letto l'interessante articolo sul client ftp presente sul sito.
le mie esigenze sono un po' diverse però e quindi espongo il mio problema.
ho creato un progetto con VS2005 di tipo console perchè necessito che il programma possa essere schedulato e non necessito dell'intervento di alcun utente (si troverà poi in un server). devo semplicemente leggere dei dati da un file (nel mio esempio l'indirizzo ftp a cui connettermi, il nome utente, la password e il nome(o i nomi) del file da scaricare.
dopo utilizzo la funzione download presente nel tutorial del client ftp.
Il mio problema principale è che scarica il file (o almeno lo costruisce in locale) però questo file è vuoto.
la mia necessità è di scaricare file non di testo (per ora sto provando con un .jpg) bensì file zip o rar.
allego il codice della mia semplice applicazione (da notare che le stringhe dal file di testo vengono lette nel modo giusto)

(tra l'altro viene lanciata un eccezione alla riga:
_FtpResponse = (FtpWebResponse)_FtpRequest.GetResponse();
)
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Net; using System.Collections; namespace ftptransfer { class Program { #region "campi dati privati" private string HOST; private string USER; private string PWD; private string FILE; private FtpWebRequest _FtpRequest; private FtpWebResponse _FtpResponse; #endregion #region "metodi pubblici" public void DownloadFile(string Path, string LocalPath, string Name) { string _fileName = LocalPath + "\\" + Name; FileInfo _File = new FileInfo(_fileName); FileStream _FileStream; _FtpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + HOST + "//" + FILE); _FtpRequest.Credentials = new NetworkCredential(USER, PWD); _FtpRequest.Method = WebRequestMethods.Ftp.DownloadFile; _FtpRequest.EnableSsl = false; _FileStream = new FileStream(_File.FullName, FileMode.Create, FileAccess.Write); _FtpResponse = (FtpWebResponse)_FtpRequest.GetResponse(); Stream _ResponseStream = _FtpResponse.GetResponseStream(); byte[] buffer = new byte[1024]; int bytesRead = _ResponseStream.Read(buffer, 0, 1024); while (bytesRead != 0) { _FileStream.Write(buffer, 0, bytesRead); bytesRead = _ResponseStream.Read(buffer, 0, 1024); } _FileStream.Close(); _ResponseStream.Close(); } #endregion #region "Main" static void Main(string[] args) { Program p = new Program(); string Nfile = "D:\\stage\\ftp.txt";//args[0]; StreamReader sr = File.OpenText(@Nfile); FileInfo fi = new FileInfo(@"D:\\stage\\ftp.txt"); sr=fi.OpenText(); p.HOST = sr.ReadLine(); System.Console.WriteLine(p.HOST); p.USER = sr.ReadLine(); System.Console.WriteLine(p.USER); p.PWD = sr.ReadLine(); System.Console.WriteLine(p.PWD); p.FILE = sr.ReadLine(); System.Console.WriteLine(p.FILE); sr.Close(); p.DownloadFile(" ", "C:\\" , "10.jpg"); } #endregion } }

ieri mi era venuto in mente di utilizzare uno script bat cosi costruito
@ECHO OFF echo open ftp.mydomain.it >> D:\Backup\script.txt echo user>> D:\Backup\script.txt echo password>> D:\Backup\script.txt echo binary>>D:\Backup\script.txt echo lcd D:\Backup>> D:\Backup\script.txt echo prompt>> D:\Backup\script.txt echo mget nome_file>> D:\Backup\script.txt echo bye>> D:\Backup\script.txt echo ftp -s:D:\Backup\ftp.bat>> D:\Backup\script.txt C:\WINDOWS\system32\ftp.exe -s:D:\Backup\script.txt del D:\Backup\script.txt exit

e questo funziona ma volevo almeno integrarlo e farlo avviare da c# in modo da avere un applicazione un po più seria e che possa essere eventualmente utilizzata dall'azienda per cui faccio lo stage.
ho cercato ovunque ma non son riuscito a trovare nulla per quanto riguarda l'esecuzione di file .bat da un applicazione c#

grazie mille a chi mi sa rispondere!!!


edit

ho quasi risolto..cioè sembra funzionare con la prima soluzione..qualcuno saprebbe illuminarmi con la seconda?

Brainkiller Profilo | Guru

>e questo funziona ma volevo almeno integrarlo e farlo avviare
>da c# in modo da avere un applicazione un po più seria e che
>possa essere eventualmente utilizzata dall'azienda per cui faccio
>lo stage.

Pensa che leggendo la prima parte di post ti stavo per consigliare anche io la costruzione di uno script esterno in Batch, che richiede molto meno tempo, è molto più affidabile e crea meno problemi.

>ho cercato ovunque ma non son riuscito a trovare nulla per quanto
>riguarda l'esecuzione di file .bat da un applicazione c#

Prova a leggere questo tip per lanciare programmi esterni .exe. Anche per i .bat dovrebbe funzionare:
http://www.dotnethell.it/tips/ComandoEsterno.aspx

Ciao

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

toyo86 Profilo | Junior Member

adesso valuto un attimo..intanto vi metto online il mio codice..

using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Net; using System.Collections; namespace ftptransfer { class Program { #region "campi dati privati" private string HOST; private string USER; private string PWD; private string FILE; private FtpWebRequest _FtpRequest; private FtpWebResponse _FtpResponse; #endregion #region "metodi pubblici" public void DownloadFile(string Path, string LocalPath, string Name) { string _fileName = LocalPath + "\\" + Name; FileInfo _File = new FileInfo(_fileName); FileStream _FileStream; _FtpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + HOST + "/" + FILE); System.Console.WriteLine("ftp://" + HOST + "/" + FILE); _FtpRequest.Credentials = new NetworkCredential(USER, PWD); _FtpRequest.Method = WebRequestMethods.Ftp.DownloadFile; _FtpRequest.EnableSsl = false; _FileStream = new FileStream(_File.FullName, FileMode.Create, FileAccess.Write); _FtpResponse = (FtpWebResponse)_FtpRequest.GetResponse(); Stream _ResponseStream = _FtpResponse.GetResponseStream(); byte[] buffer = new byte[1024]; int bytesRead = _ResponseStream.Read(buffer, 0, 1024); while (bytesRead != 0) { _FileStream.Write(buffer, 0, bytesRead); bytesRead = _ResponseStream.Read(buffer, 0, 1024); } _FileStream.Close(); _ResponseStream.Close(); } #endregion #region "Main" static void Main(string[] args) { Program p = new Program(); string Nfile = "D:\\stage\\ftp.txt"; StreamReader sr = File.OpenText(@Nfile); FileInfo fi = new FileInfo(@"D:\\stage\\ftp.txt"); sr=fi.OpenText(); p.HOST = sr.ReadLine(); System.Console.WriteLine("Mi sto collegando all'host: "+p.HOST); p.USER = sr.ReadLine(); //System.Console.WriteLine(p.USER); p.PWD = sr.ReadLine(); //System.Console.WriteLine(p.PWD); while(!sr.EndOfStream) { p.FILE = sr.ReadLine(); System.Console.WriteLine("Cerco di scaricare "+p.FILE); try { p.DownloadFile(" ", "C:", p.FILE); System.Console.WriteLine("File " + p.FILE + " scaricato"); } catch (Exception e) { System.Console.WriteLine("attenzione all'eccezione..."); } } System.Console.WriteLine("file scaricati..."); sr.Close(); } #endregion } }

questo funziona se il file da cui va a pescare i dati è cosi formato:
indirizzoftp nomeutente password file1.xxx file2.xxx (e cosi via..)
mi raccomando tutto scritto su righe differenti..una limitazione sta nel fatto che bisogna conoscere i nomi dei file da scaricare prima..però questo può tornare comodo se il file (o i file) da prendere nel server ftp sono sempre gli stessi o hanno sempre lo stesso nome..per il mio lavoro infatti i file si chiamano sempre nello stesso modo..quindi mi basta schedulare il programma nelle attività pianificate e parte da solo senza alcun mio intervento se non nell'impostazione del file la prima volta...

Brainkiller Profilo | Guru

>sempre nello stesso modo..quindi mi basta schedulare il programma
>nelle attività pianificate e parte da solo senza alcun mio intervento
>se non nell'impostazione del file la prima volta...

Ti indico inoltre l'esistenza di due istruzioni FTP, MPUT e MGET che servono per fare multiple get o multiple put.
Funzionano anche con le wildcard esempio:

mget *.gif

per scaricare tutti i .gif.
Magari ti può essere utile.
Ciao

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

toyo86 Profilo | Junior Member

molto interessante..ma è un comando ftp ed è disponibile nelle classi che uso io?

Brainkiller Profilo | Guru

>molto interessante..ma è un comando ftp ed è disponibile nelle
>classi che uso io?

Sono comandi FTP. Tanti li ignorano e spesso non sapendo i nomi dei file sull'FTP non sanno come scaricare i files se non dopo averli enumerati. Ma visto che in genere i file sono o tutti della stessa estensione o comunque hanno un prefisso o parti del nome in comune (nel caso di file esportati in processi di business) è facile con MGET scaricare ciò di cui si ha bisogno.
Ciao

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

toyo86 Profilo | Junior Member

ok..ma posso far eseguire questo comando una volta che mi sono collegato al ftp?nel senso..
nel programma che ho scritto in c# c'è un modo di far eseguire il comando get *.rar ad esempio?visto che devo scaricare solo file .rar però non so quanti siano..

Brainkiller Profilo | Guru

>ok..ma posso far eseguire questo comando una volta che mi sono
>collegato al ftp?nel senso..
>nel programma che ho scritto in c# c'è un modo di far eseguire
>il comando get *.rar ad esempio?visto che devo scaricare solo
>file .rar però non so quanti siano..

Questo comando che ti ho indicato io sarebbe da usare nella soluzione n°2 cioè quella basata su script. Immagino che comunque il comando MGET o MPUT possa essere usato anche nella prima soluzione visto che sono comandi Standard FTP.
Ciao

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

toyo86 Profilo | Junior Member

eccomi qua..ho trovato la seconda soluzione...tramite script lanciato dall'applicazione c#
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Net; using System.Collections; namespace ftptransfer { class Program { #region "campi dati privati" private string HOST; private string USER; private string PWD; #endregion #region "metodi pubblici" #endregion #region "Main" static void Main(string[] args) { Program p = new Program(); string Nfile = "credenziali.txt";//args[0]; StreamReader sr = File.OpenText(@Nfile); FileInfo fi = new FileInfo(@"credenziali.txt"); sr = fi.OpenText(); p.HOST = sr.ReadLine(); System.Console.WriteLine("Mi sto collegando all'host: " + p.HOST); p.USER = sr.ReadLine(); //System.Console.WriteLine(p.USER); p.PWD = sr.ReadLine(); //System.Console.WriteLine(p.PWD); sr.Close(); //scrivo il file di script FileStream fs=new FileStream("ftp.bat", FileMode.Create); //BinaryWriter bw=new BinaryWriter(fs); StreamWriter swr = new StreamWriter(fs); swr.WriteLine("@ECHO OFF"); swr.WriteLine("echo open " + p.HOST + ">> .\\script.txt"); swr.WriteLine("echo " + p.USER + ">> .\\script.txt"); swr.WriteLine("echo " + p.PWD + ">> .\\script.txt"); swr.WriteLine("echo binary>> .\\script.txt"); swr.WriteLine("echo lcd .>> .\\script.txt"); swr.WriteLine("echo prompt>> .\\script.txt"); swr.WriteLine("echo mget *.rar>> .\\script.txt"); swr.WriteLine("echo bye>> .\\script.txt"); swr.WriteLine("echo ftp -s:.\\ftp.bat>> .\\script.txt"); swr.WriteLine("C:\\WINDOWS\\system32\\ftp.exe -s:.\\script.txt"); swr.WriteLine("del .\\script.txt"); swr.WriteLine("exit"); swr.Close(); System.Diagnostics.Process.Start("ftp.bat", ""); } #endregion } }

ecco alcuni commenti...
credenziali.txt dev'essere nella stessa cartella dell'eseguibile e dev essere cosi formato..
host ftp
nome utente
password

nel codice sono rispettivamente HOST, USER e PWD.

grazie a tutti e se avete domande chiedete!!

toyo86 Profilo | Junior Member

in allegato aggiungo il compilato del progettino finito!se volete il codice chiedete pure..ma se non sbaglio è solo quello che ho postato pulito dai commenti!!!
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5