Barra de progreso de la línea de comando en Java
command-line progress-bar (11)
Tengo un programa Java ejecutándose en modo de línea de comando. Me gustaría mostrar una barra de progreso que muestre el porcentaje de trabajo realizado. El mismo tipo de barra de progreso que vería usando wget bajo Unix. es posible?
Aquí hay una versión modificada de lo anterior:
private static boolean loading = true;
private static synchronized void loading(String msg) throws IOException, InterruptedException {
System.out.println(msg);
Thread th = new Thread() {
@Override
public void run() {
try {
System.out.write("/r|".getBytes());
while(loading) {
System.out.write("-".getBytes());
Thread.sleep(500);
}
System.out.write("| Done /r/n".getBytes());
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
th.start();
}
... y en principal:
loading("Calculating ...");
Ejemplo de C # pero asumo que esto es lo mismo para System.out.print
en Java. Siéntete libre de corregirme si me equivoco.
Básicamente, desea escribir el carácter de escape al inicio de su mensaje, lo que hará que el cursor regrese al inicio de la línea (Line Feed) sin moverse a la siguiente línea.
static string DisplayBar(int i)
{
StringBuilder sb = new StringBuilder();
int x = i / 2;
sb.Append("|");
for (int k = 0; k < 50; k++)
sb.AppendFormat("{0}", ((x <= k) ? " " : "="));
sb.Append("|");
return sb.ToString();
}
static void Main(string[] args)
{
for (int i = 0; i <= 100; i++)
{
System.Threading.Thread.Sleep(200);
Console.Write("/r{0} {1}% Done", DisplayBar(i), i);
}
Console.ReadLine();
}
Encontré el siguiente código para que funcione correctamente. Escribe bytes en el búfer de salida. Quizás los métodos que utilizan un escritor como el método System.out.println()
reemplazan las ocurrencias de /r
a /n
para que coincida con la terminación de línea nativa del objetivo (si no está configurado correctamente).
public class Main{
public static void main(String[] arg) throws Exception {
String anim= "|/-//";
for (int x =0 ; x < 100 ; x++) {
String data = "/r" + anim.charAt(x % anim.length()) + " " + x;
System.out.write(data.getBytes());
Thread.sleep(100);
}
}
}
Esto sería posible con una biblioteca Java Curses. This es lo que he encontrado. No lo he usado yo mismo y no sé si es multiplataforma.
Hay https://github.com/ctongfei/progressbar , Licencia: MIT
Barra de progreso simple de la consola. La escritura de la barra de progreso ahora se ejecuta en otro hilo.
Menlo, Fira Mono, Source Code Pro o SF Mono se recomiendan para efectos visuales óptimos.
Para las fuentes Consolas o Andale Mono, use ProgressBarStyle.ASCII
(consulte a continuación) porque los glifos de dibujo de cuadro no están alineados correctamente en estas fuentes.
Maven:
<dependency>
<groupId>me.tongfei</groupId>
<artifactId>progressbar</artifactId>
<version>0.5.5</version>
</dependency>
Uso:
ProgressBar pb = new ProgressBar("Test", 100); // name, initial max
// Use ProgressBar("Test", 100, ProgressBarStyle.ASCII) if you want ASCII output style
pb.start(); // the progress bar starts timing
// Or you could combine these two lines like this:
// ProgressBar pb = new ProgressBar("Test", 100).start();
some loop {
...
pb.step(); // step by 1
pb.stepBy(n); // step by n
...
pb.stepTo(n); // step directly to n
...
pb.maxHint(n);
// reset the max of this progress bar as n. This may be useful when the program
// gets new information about the current progress.
// Can set n to be less than zero: this means that this progress bar would become
// indefinite: the max would be unknown.
...
pb.setExtraMessage("Reading..."); // Set extra message to display at the end of the bar
}
pb.stop() // stops the progress bar
He implementado este tipo de cosas antes. No se trata tanto de java, sino de qué personajes enviar a la consola.
La clave es la diferencia entre /n
y /r
. /n
va al comienzo de una nueva línea. Pero es solo el retorno del carro , vuelve al comienzo de la misma línea.
Entonces, lo que hay que hacer es imprimir su barra de progreso, por ejemplo, imprimiendo la cadena
"|======== |/r"
En el siguiente tic de la barra de progreso, sobrescriba la misma línea con una barra más larga. (porque estamos usando / r, nos mantenemos en la misma línea) Por ejemplo:
"|========= |/r"
Lo que debe recordar hacer es cuando termine, si solo imprime
"done!/n"
Aún puede tener algo de basura de la barra de progreso en la línea. Entonces, cuando haya terminado con la barra de progreso, asegúrese de imprimir suficiente espacio en blanco para eliminarla de la línea. Como:
"done |/n"
Espero que ayude.
Hice un progreso porcentual para verificar el archivo de descarga restante.
Llamo periódicamente al método en la descarga de mi archivo para verificar el tamaño total del archivo y lo que queda y lo presento en %
.
También se puede usar para otros fines de tareas.
Ejemplo de prueba y salida
progressPercentage(0, 1000);
[----------] 0%
progressPercentage(10, 100);
[*---------] 10%
progressPercentage(500000, 1000000);
[*****-----] 50%
progressPercentage(90, 100);
[*********-] 90%
progressPercentage(1000, 1000);
[**********] 100%
Prueba con for loop
for (int i = 0; i <= 200; i = i + 20) {
progressPercentage(i, 200);
try {
Thread.sleep(500);
} catch (Exception e) {
}
}
El método se puede modificar fácilmente:
public static void progressPercentage(int remain, int total) {
if (remain > total) {
throw new IllegalArgumentException();
}
int maxBareSize = 10; // 10unit for 100%
int remainProcent = ((100 * remain) / total) / maxBareSize;
char defaultChar = ''-'';
String icon = "*";
String bare = new String(new char[maxBareSize]).replace(''/0'', defaultChar) + "]";
StringBuilder bareDone = new StringBuilder();
bareDone.append("[");
for (int i = 0; i < remainProcent; i++) {
bareDone.append(icon);
}
String bareRemain = bare.substring(remainProcent, bare.length());
System.out.print("/r" + bareDone + bareRemain + " " + remainProcent * 10 + "%");
if (remain == total) {
System.out.print("/n");
}
}
Recientemente me he enfrentado al mismo problema, puede verificar mi código: lo configuré para un # en un 5%, que puede modificar más adelante.
public static void main (String[] args) throws java.lang.Exception
{
int i = 0;
while(i < 21) {
System.out.print("[");
for (int j=0;j<i;j++) {
System.out.print("#");
}
for (int j=0;j<20-i;j++) {
System.out.print(" ");
}
System.out.print("] "+ i*5 + "%");
if(i<20) {
System.out.print("/r");
Thread.sleep(300);
}
i++;
}
System.out.println();
}
Utilizo una barra de progreso de "rebote" cuando necesito retrasar una herramienta para evitar una condición de carrera.
private void delay(long milliseconds) {
String bar = "[--------------------]";
String icon = "%";
long startTime = new Date().getTime();
boolean bouncePositive = true;
int barPosition = 0;
while((new Date().getTime() - startTime) < milliseconds) {
if(barPosition < bar.length() && barPosition > 0) {
String b1 = bar.substring(0, barPosition);
String b2 = bar.substring(barPosition);
System.out.print("/r Delaying: " + b1 + icon + b2);
if(bouncePositive) barPosition++;
else barPosition--;
} if(barPosition == bar.length()) {
barPosition--;
bouncePositive = false;
} if(barPosition == 0) {
barPosition++;
bouncePositive = true;
}
try { Thread.sleep(100); }
catch (Exception e) {}
}
System.out.print("/n");
}
public class ProgressBar
{
private int max;
public ProgressBar(int max0) {
max = max0;
update(0);
}
public void update(int perc) {
String toPrint = "|";
for(int i = 0; i < max; i++) {
if(i <= (perc + 1))
toPrint += "=";
else
toPrint += " ";
}
if(perc >= max)
Console.print("/r");
else
Console.print(toPrint + "|/r");
}
}
public static void main(String[] argv) throws Exception{
System.out.write("/r".getBytes());
int percentage =10;
while(percentage <= 100) {
String temp =generateStars(percentage);
System.out.write(temp.getBytes());
System.out.print("/b/b/b");
percentage = percentage+10;
Thread.sleep(500);
}
}
public static String generateStars(int percentage)
{
int startsNum = percentage / 4;
StringBuilder builder = new StringBuilder();
while(startsNum >= 0)
{
builder.append("*");
startsNum--;
}
builder.append(percentage+"%");
return builder.toString();
}