Barre de progression dans l’application console

J’écris une simple application de console c # qui télécharge des fichiers sur le serveur sftp. Cependant, la quantité de fichiers est importante. Je souhaite afficher soit le pourcentage de fichiers téléchargés, soit uniquement le nombre de fichiers à télécharger à partir du nombre total de fichiers à télécharger.

Premièrement, je reçois tous les fichiers et le nombre total de fichiers.

ssortingng[] filePath = Directory.GetFiles(path, "*"); totalCount = filePath.Length; 

Ensuite, je parcoure le fichier et les télécharge un par un dans la boucle foreach.

 foreach(ssortingng file in filePath) { ssortingng FileName = Path.GetFileName(file); //copy the files oSftp.Put(LocalDirectory + "/" + FileName, _ftpDirectory + "/" + FileName); //Console.WriteLine("Uploading file..." + FileName); drawTextProgressBar(0, totalCount); } 

Dans la boucle foreach, j’ai une barre de progression avec laquelle j’ai des problèmes. Il ne s’affiche pas correctement.

 private static void drawTextProgressBar(int progress, int total) { //draw empty progress bar Console.CursorLeft = 0; Console.Write("["); //start Console.CursorLeft = 32; Console.Write("]"); //end Console.CursorLeft = 1; float onechunk = 30.0f / total; //draw filled part int position = 1; for (int i = 0; i < onechunk * progress; i++) { Console.BackgroundColor = ConsoleColor.Gray; Console.CursorLeft = position++; Console.Write(" "); } //draw unfilled part for (int i = position; i <= 31 ; i++) { Console.BackgroundColor = ConsoleColor.Green; Console.CursorLeft = position++; Console.Write(" "); } //draw totals Console.CursorLeft = 35; Console.BackgroundColor = ConsoleColor.Black; Console.Write(progress.ToString() + " of " + total.ToString() + " "); //blanks at the end remove any excess } 

La sortie est juste [] 0 sur 1943

Que fais-je mal ici?

MODIFIER:

J’essaie d’afficher la barre de progression pendant le chargement et l’exportation de fichiers XML. Cependant, cela passe par une boucle. Après avoir terminé le premier tour, il passe à la seconde et ainsi de suite.

 ssortingng[] xmlFilePath = Directory.GetFiles(xmlFullpath, "*.xml"); Console.WriteLine("Loading XML files..."); foreach (ssortingng file in xmlFilePath) { for (int i = 0; i < xmlFilePath.Length; i++) { //ExportXml(file, styleSheet); drawTextProgressBar(i, xmlCount); count++; } } 

Il ne laisse jamais la boucle pour… Des suggestions?

Cette ligne est votre problème:

 drawTextProgressBar(0, totalCount); 

Vous dites que la progression est nulle à chaque itération, cela devrait être incrémenté. Peut-être utiliser plutôt une boucle for.

 for (int i = 0; i < filePath.length; i++) { string FileName = Path.GetFileName(filePath[i]); //copy the files oSftp.Put(LocalDirectory + "/" + FileName, _ftpDirectory + "/" + FileName); //Console.WriteLine("Uploading file..." + FileName); drawTextProgressBar(i, totalCount); } 

Je cherchais aussi une barre de progression de la console. Je n’ai pas trouvé celui qui a fait ce dont j’avais besoin, alors j’ai décidé de rouler moi-même. Cliquez ici pour le code source (licence MIT).

Barre de progression animée

Caractéristiques:

  • Fonctionne avec une sortie redirigée

    Si vous redirigez la sortie d’une application console (par exemple, Program.exe > myfile.txt ), la plupart des implémentations Program.exe > myfile.txt panne avec une exception. C’est parce que Console.CursorLeft et Console.SetCursorPosition() ne prennent pas en charge la sortie redirigée.

  • Implémente IProgress

    Cela vous permet d’utiliser la barre de progression avec les opérations asynchrones qui signalent une progression dans la plage de [0..1].

  • Filetage sécurisé

  • Vite

    La classe de la Console est notoire pour ses performances abyssales. Trop d’appels, et votre application ralentit. Cette classe effectue seulement 8 appels par seconde, quelle que soit la fréquence à laquelle vous signalez une mise à jour de progression.

Utilisez-le comme ceci:

 Console.Write("Performing some task... "); using (var progress = new ProgressBar()) { for (int i = 0; i < = 100; i++) { progress.Report((double) i / 100); Thread.Sleep(20); } } Console.WriteLine("Done."); 

Je sais que c’est un ancien sujet, et je vous présente mes excuses pour l’auto-promotion, mais j’ai récemment écrit une bibliothèque de console open source disponible sur nuget Goblinfactory.Konsole avec un support de barre de progression multiple. ne bloque pas le thread principal.

C’est un peu différent des réponses ci-dessus, car il vous permet de lancer les téléchargements et les tâches en parallèle et de poursuivre d’autres tâches.

bravo, j’espère que c’est utile

UNE

 var t1 = Task.Run(()=> { var p = new ProgressBar("downloading music",10); ... do stuff }); var t2 = Task.Run(()=> { var p = new ProgressBar("downloading video",10); ... do stuff }); var t3 = Task.Run(()=> { var p = new ProgressBar("starting server",10); ... do stuff .. calling p.Refresh(n); }); Task.WaitAll(new [] { t1,t2,t3 }, 20000); Console.WriteLine("all done."); 

vous donne ce type de sortie

entrer la description de l'image ici

Le package nuget comprend également des utilitaires permettant d’écrire dans une section fenêtrée de la console avec une prise en charge complète de la découpe et de l’emballage, ainsi que PrintAt et diverses autres classes utiles.

J’ai écrit le paquet nuget parce que je finissais toujours par écrire de nombreuses routines de console communes à chaque fois que je rédigeais des scripts et des utilitaires de console de construction et d’exploitation.

Si je téléchargeais plusieurs fichiers, j’avais l’habitude d’utiliser Console.Write sur l’écran de chaque thread et d’essayer différentes astuces pour faciliter la lecture de la sortie entrelacée sur l’écran, par exemple des couleurs ou des nombres différents. J’ai finalement écrit la bibliothèque de fenêtres pour que les sorties de différents threads puissent simplement être imprimées sur différentes fenêtres, et cela a réduit une tonne de code standard dans mes scripts utilitaires.

Par exemple, ce code,

  var con = new Window(200,50); con.WriteLine("starting client server demo"); var client = new Window(1, 4, 20, 20, ConsoleColor.Gray, ConsoleColor.DarkBlue, con); var server = new Window(25, 4, 20, 20, con); client.WriteLine("CLIENT"); client.WriteLine("------"); server.WriteLine("SERVER"); server.WriteLine("------"); client.WriteLine("< -- PUT some long text to show wrapping"); server.WriteLine(ConsoleColor.DarkYellow, "--> PUT some long text to show wrapping"); server.WriteLine(ConsoleColor.Red, "< -- 404|Not Found|some long text to show wrapping|"); client.WriteLine(ConsoleColor.Red, "--> 404|Not Found|some long text to show wrapping|"); con.WriteLine("starting names demo"); // let's open a window with a box around it by using Window.Open var names = Window.Open(50, 4, 40, 10, "names"); TestData.MakeNames(40).OrderByDescending(n => n).ToList() .ForEach(n => names.WriteLine(n)); con.WriteLine("starting numbers demo"); var numbers = Window.Open(50, 15, 40, 10, "numbers", LineThickNess.Double,ConsoleColor.White,ConsoleColor.Blue); Enumerable.Range(1,200).ToList() .ForEach(i => numbers.WriteLine(i.ToSsortingng())); // shows scrolling 

produit cela

entrer la description de l'image ici

Vous pouvez également créer des barres de progression dans une fenêtre aussi facilement que si vous écrivez dans les fenêtres. (mélanger et assortir).

J’ai copié votre méthode ProgressBar collée. Parce que votre erreur était dans la boucle comme indiqué dans la réponse acceptée. Mais la méthode ProgressBar comporte également des erreurs de syntaxe. Voici la version de travail. Légèrement modifié.

 private static void ProgressBar(int progress, int tot) { //draw empty progress bar Console.CursorLeft = 0; Console.Write("["); //start Console.CursorLeft = 32; Console.Write("]"); //end Console.CursorLeft = 1; float onechunk = 30.0f / tot; //draw filled part int position = 1; for (int i = 0; i < onechunk * progress; i++) { Console.BackgroundColor = ConsoleColor.Green; Console.CursorLeft = position++; Console.Write(" "); } //draw unfilled part for (int i = position; i <= 31; i++) { Console.BackgroundColor = ConsoleColor.Gray; Console.CursorLeft = position++; Console.Write(" "); } //draw totals Console.CursorLeft = 35; Console.BackgroundColor = ConsoleColor.Black; Console.Write(progress.ToString() + " of " + tot.ToString() + " "); //blanks at the end remove any excess } 

Veuillez noter que @ Daniel-wolf a une meilleure approche: https://stackoverflow.com/a/31193455/169714

J’ai bien aimé la barre de progression de l’affiche originale, mais j’ai constaté qu’elle ne affichait pas correctement la progression avec certaines combinaisons de progression / éléments totaux. Le suivant, par exemple, ne dessine pas correctement, en laissant un bloc gris supplémentaire à la fin de la barre de progression:

 drawTextProgressBar(4114, 4114) 

J’ai refait une partie du code de dessin pour supprimer le bouclage inutile qui corrige le problème ci-dessus et a également accéléré un peu le processus:

 public static void drawTextProgressBar(ssortingng stepDescription, int progress, int total) { int totalChunks = 30; //draw empty progress bar Console.CursorLeft = 0; Console.Write("["); //start Console.CursorLeft = totalChunks + 1; Console.Write("]"); //end Console.CursorLeft = 1; double pctComplete = Convert.ToDouble(progress) / total; int numChunksComplete = Convert.ToInt16(totalChunks * pctComplete); //draw completed chunks Console.BackgroundColor = ConsoleColor.Green; Console.Write("".PadRight(numChunksComplete)); //draw incomplete chunks Console.BackgroundColor = ConsoleColor.Gray; Console.Write("".PadRight(totalChunks - numChunksComplete)); //draw totals Console.CursorLeft = totalChunks + 5; Console.BackgroundColor = ConsoleColor.Black; ssortingng output = progress.ToSsortingng() + " of " + total.ToSsortingng(); Console.Write(output.PadRight(15) + stepDescription); //pad the output so when changing from 3 to 4 digits we avoid text shifting } 

Je suis juste tombé sur ce fil à la recherche de quelque chose d’autre, et j’ai pensé déposer mon code que je rassemble pour télécharger une liste de fichiers à l’aide de DownloadProgressChanged. Je trouve cela très utile, donc je ne vois pas seulement les progrès, mais aussi la taille réelle du fichier. J’espère que ça aide quelqu’un!

 public static bool DownloadFile(List files, ssortingng host, ssortingng username, ssortingng password, ssortingng savePath) { try { //setup FTP client foreach (ssortingng f in files) { FILENAME = f.Split('\\').Last(); wc.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed); wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged); wc.DownloadFileAsync(new Uri(host + f), savePath + f); while (wc.IsBusy) System.Threading.Thread.Sleep(1000); Console.Write(" COMPLETED!"); Console.WriteLine(); } } catch (Exception ex) { Console.WriteLine(ex.ToSsortingng()); return false; } return true; } private static void ProgressChanged(object obj, System.Net.DownloadProgressChangedEventArgs e) { Console.Write("\r --> Downloading " + FILENAME +": " + ssortingng.Format("{0:n0}", e.BytesReceived / 1000) + " kb"); } private static void Completed(object obj, AsyncCompletedEventArgs e) { } 

Voici un exemple de sortie: entrer la description de l'image ici

J’espère que ça aide quelqu’un!

Vous voudrez peut-être essayer https://www.nuget.org/packages/ShellProgressBar/

Je suis juste tombé sur cette implémentation de barre de progression – sa plate-forme croisée, très facile à utiliser, tout à fait configurable et qui fait tout ce qu’il faut dès la sortie de la boîte.

Je partage juste parce que j’ai beaucoup aimé.

Je suis encore un peu nouveau à C# mais je crois que le ci-dessous pourrait aider.

 ssortingng[] xmlFilePath = Directory.GetFiles(xmlFullpath, "*.xml"); Console.WriteLine("Loading XML files..."); int count = 0; foreach (ssortingng file in xmlFilePath) { //ExportXml(file, styleSheet); drawTextProgressBar(count, xmlCount); count++; }