Индикатор выполнения командной строки в Java

У меня есть программа Java, работающая в режиме командной строки. Я хотел бы отобразить индикатор выполнения, показывая процент выполненной работы. Такой же индикатор прогресса, который вы увидите, используя wget под unix. Возможно ли это?

Ответ 1

Я уже делал это раньше. Это не столько о Java, сколько о том, какие символы отправлять на консоль.

Ключ - это разница между \n и \r. \n переходит в начало новой строки. Но \r - это только возврат каретки - он возвращается к началу той же строки.

Итак, вам нужно распечатать индикатор выполнения, например, напечатав строку

"|========        |\r"

При следующем тике индикатора выполнения перепишите одну строку с более длинной полосой. (потому что мы используем \r, мы остаемся в одной строке) Например:

"|=========       |\r"

Что вы должны помнить, когда это делается, если вы просто напечатаете

"done!\n"

У вас все еще есть мусор из индикатора выполнения на линии. Поэтому после того, как вы закончите работу с индикатором выполнения, обязательно напечатайте достаточно пробелов, чтобы удалить его из строки. Например:

"done             |\n"

Надеюсь, что это поможет.

Ответ 2

Я нашел, что следующий код работает правильно. Он записывает байты в выходной буфер. Возможно, методы, использующие сценарий типа System.out.println(), заменяют вхождения от \r до \n в соответствии с окончанием конечной конечной строки (если не настроены правильно).

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);
        }
    }
}

Ответ 3

Есть https://github.com/ctongfei/progressbar, Лицензия: MIT

Простой консольный индикатор. Запись индикатора выполнения теперь выполняется в другом потоке.

1c02d51927e769cf245a108f5a8dfaf5.gif

Menlo, Fira Mono, Source Code Pro или SF Mono рекомендуются для оптимальных визуальных эффектов.

Для шрифтов Consolas или Andale Mono используйте ProgressBarStyle.ASCII (см. Ниже), поскольку глифы для рисования блоков не выровнены должным образом в этих шрифтах.

e01943454443f90c9499c00a6c197a41.gif

Maven:

<dependency>
  <groupId>me.tongfei</groupId>
  <artifactId>progressbar</artifactId>
  <version>0.5.5</version>
</dependency>

Использование:

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

Ответ 4

С# Пример, но я предполагаю, что это то же самое для System.out.print в Java. Не стесняйтесь исправить меня, если я ошибаюсь.

В принципе, вы хотите записать escape-символ \r в начало вашего сообщения что приведет к тому, что курсор вернется к началу строки (Line Feed), не перейдя к следующей строке.

    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();

    }

Ответ 5

Я сделал процентный прогресс, чтобы проверить оставшийся файл загрузки.

Я периодически вызываю метод в моей загрузке файла, чтобы проверить общий размер файла, а остальное и присутствует, что в %.

Его можно использовать и для других задач.

Пример тестирования и вывода

progressPercentage(0, 1000);
[----------] 0%

progressPercentage(10, 100);
[*---------] 10%

progressPercentage(500000, 1000000);
[*****-----] 50%

progressPercentage(90, 100);
[*********-] 90%

progressPercentage(1000, 1000);
[**********] 100%

Тест с циклом

for (int i = 0; i <= 200; i = i + 20) {
    progressPercentage(i, 200);
    try {
        Thread.sleep(500);
    } catch (Exception e) {
    }
}

Метод можно легко изменить:

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");
    }
}

Ответ 6

Ниже приведена модифицированная версия:

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();
}

... и в основном:

loading("Calculating ...");

Ответ 7

Это возможно с помощью библиотеки Java Curses. Это, что я нашел. Я не использовал его сам, и я не знаю, является ли это кросс-платформенным.

Ответ 8

Я использую "прыгающий" индикатор выполнения, когда мне нужно отложить инструмент, чтобы предотвратить состояние гонки.

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");
}

Ответ 9

Недавно я столкнулся с такой же проблемой, вы можете проверить мой код: Я установил его для одного # на 5%, который вы можете изменить позже.

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();
}

Ответ 10

while (true) {
        System.out.write(("\r" + System.currentTimeMillis()).getBytes());
        Thread.sleep(1000);
}

Ответ 11

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();
    }

Ответ 12

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");
    }
}

Ответ 13

public class Main {

    public static void main(String[] args) throws Exception {

        System.out.println("Loading : ");
            int count =1;
            for(int j=1;j<150;j++){

                System.out.print("\r");
                if(count==1){
                    System.out.print("/");
                    count++;
                }
                else if(count==2){
                    System.out.print("|");
                    count++;
                }
                else if(count==3){
                    System.out.print("-");
                    count++;
                }
                else if(count==4){
                    System.out.print("\\");
                    count++;
                }
                else if(count==5){
                    System.out.print("|");
                    count++;
                }
                else
                    count = 1;
            Thread.sleep(200);
        }

        }

    }