Quan per Nadal graven uns vídeos dels nens fent els pastorets i tens que compartir 3.5GB amb persones que tenen pocs coneixements d'informàtica a.k.a usuaris, i el tema pendrive no mola. No mola pel tema pandèmia i per que els usuaris són despistats i els pendrives no tornen.
Donat que tinc un servidor de SFTP a casa i que explicar com instal·lar i configurar un client de SFTP a segons qui doncs li pot donar un yuyu cerebral, o simplement no té temps ni ganes d'aprendre, cal fer algo fàcil de fer servir.
Doncs dit i fet, un programet dummy on hi ha un client de SFTP amb la configuració posada i el que ha de descarregar també. Ah! I com a bonus track donat que els usuaris van per Wifi, ara falla ara no, ara tenen una estona per descarregar, ara paren a descansar... Doncs té la funció "resume" o que continua allà on ho ha deixat.
El codi a continuació, és una aplicació Winforms de tota la vida, el formulari té dos botons, una barra de progrés i un quadre de text.
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Renci.SshNet;
using Renci.SshNet.Common;
using Renci.SshNet.Sftp;
namespace Downloader
{
public partial class frmDownloader : Form
{
bool EnMarxa = false;
public frmDownloader()
{
InitializeComponent();
}
private delegate void SetLogDelegate(string propertyValue);
public void SetLog(string propertyValue)
{
if (this.InvokeRequired)
{
this.Invoke(new SetLogDelegate(SetLog), propertyValue);
}
else
{
if (txtLog.Text.Length > 10000) txtLog.Text = "";
txtLog.Text += Environment.NewLine + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString() + " - " + propertyValue;
}
}
public string ObtenirIP(string host)
{
IPHostEntry hostEntry;
string adreca = "";
hostEntry = Dns.GetHostEntry(host);
if (hostEntry.AddressList.Length > 0)
{
IPAddress ip = hostEntry.AddressList[0];
adreca = ip.ToString();
}
return adreca;
}
private void btnDownload_Click(object sender, EventArgs e)
{
btnDownload.Enabled = false;
string host = @"sftp.elteudomini.aqui";
string username = "posaixo";
string password = @"aixoaltra";
string carpetaLocal;
List<clsCarpeta> CarpetesABaixar = new List<clsCarpeta>();
ConfiguracioABaixar(CarpetesABaixar);
string localDirectoryBase = AppDomain.CurrentDomain.BaseDirectory;
EnMarxa = true;
try
{
SetLog("Intentant conectar: " + host + " - " + ObtenirIP(host));
using (SftpClient client = new SftpClient(host, username, password))
{
try
{
client.Connect();
}
catch (Exception Ex)
{
SetLog("Error conectant: " + Ex.Message);
}
if (!client.IsConnected)
{
SetLog("Client no ha conectat");
return;
}
else
{
SetLog("Conectat OK");
}
foreach (clsCarpeta Carpeta in CarpetesABaixar)
{
carpetaLocal = localDirectoryBase + Carpeta.NomLocal;
if (!Directory.Exists(carpetaLocal))
{
Directory.CreateDirectory(carpetaLocal);
}
foreach (clsFitxer Fitxer in Carpeta.Fitxers)
{
DescarregaFitxer(Fitxer, Carpeta, client);
}
}
}
}
catch(Exception Err)
{
SetLog("ERROR: " + Err.Message);
}
SetLog("Acabat");
btnDownload.Enabled = true;
}
private void DescarregaFitxer(clsFitxer fitxer, clsCarpeta carpeta, SftpClient client)
{
int numIntents = 0;
int maxIntents = 10;
bool retry = false;
float percentatgeFet = 0;
string localDirectory = AppDomain.CurrentDomain.BaseDirectory + carpeta.NomLocal;
string NomSencerFitxerRemot = carpeta.NomRemot + fitxer.Nom;
do
{
bool retrying = retry;
retry = false;
if (!client.Exists(NomSencerFitxerRemot))
{
SetLog("Fitxer remot no trobat: " + NomSencerFitxerRemot);
return;
}
SetLog("Obtenint atributs del fitxer: " + NomSencerFitxerRemot);
SftpFileAttributes atributs = client.GetAttributes(NomSencerFitxerRemot);
long MidaTotal = atributs.Size;
fitxer.Mida = MidaTotal;
SetLog("Mida del fitxer a descarregar: " + MidaTotal);
string destinationFile = Path.Combine(localDirectory, fitxer.Nom);
SetLog("Grabant fitxer a: " + destinationFile);
if (File.Exists(destinationFile))
{
FileInfo infoFitxerLocal = new FileInfo(destinationFile);
if (infoFitxerLocal.Length == fitxer.Mida)
{
SetLog("Fitxer " + fitxer.Nom + " ja descarregat, saltant al següent");
return;
}
else
{
retrying = true;
}
}
try
{
Stream destinationStream;
try
{
if (retrying)
{
SetLog("Continuant descarrega");
destinationStream = new FileStream(destinationFile, FileMode.Append);
}
else
{
SetLog("Descarrega nova de cero");
destinationStream = new FileStream(destinationFile, FileMode.Create);
}
}
catch (Exception Err)
{
SetLog("No s'ha pogut crear el fitxer local: " + destinationFile);
SetLog(Err.Message);
return;
}
using (destinationStream)
using (SftpFileStream sourceStream = client.Open(NomSencerFitxerRemot, FileMode.Open))
{
sourceStream.Seek(destinationStream.Length, SeekOrigin.Begin);
byte[] buffer = new byte[81920];
int read;
long total = destinationStream.Length;
while ((read = sourceStream.Read(buffer, 0, buffer.Length)) != 0)
{
destinationStream.Write(buffer, 0, read);
total = total + (long)read;
percentatgeFet = ((float)total / (float)MidaTotal) * 100;
prgBarDescarregat.Value = (int)Math.Truncate(percentatgeFet);
lblProgress.Text = Math.Round(percentatgeFet, 2) + "%";
Application.DoEvents();
if (!EnMarxa)
{
client.Disconnect();
return;
}
}
}
}
catch (SshException ex)
{
SetLog("Error: " + ex.Message);
retry = true;
numIntents++;
SetLog("Reintents: " + numIntents);
if (numIntents > maxIntents)
{
SetLog("Sortint per mases reintents: " + numIntents);
break;
}
}
}
while (retry);
}
private void ConfiguracioABaixar(List<clsCarpeta> carpetesABaixar)
{
clsCarpeta Carpeta;
clsFitxer Fitxer;
Carpeta = new clsCarpeta();
Carpeta.NomLocal = "Harry Potter";
Carpeta.NomRemot = "/Incoming2/Pelis infantils/Harry Potter/";
Fitxer = new clsFitxer();
Fitxer.Nom = "bla bla bla 1.mkv";
Carpeta.Fitxers.Add(Fitxer);
Fitxer = new clsFitxer();
Fitxer.Nom = "Bla bla bla 2.mkv";
Carpeta.Fitxers.Add(Fitxer);
carpetesABaixar.Add(Carpeta);
}
private void btnTancar_Click(object sender, EventArgs e)
{
EnMarxa = false;
Application.Exit();
}
}
}
|