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


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

11 104

11 ответов:

я реализовал что-то подобное. Его не так много о java, но какие символы отправлять на консоль.

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

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

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

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

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

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

"done!\n"

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

"done             |\n"

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

Я нашел следующий код, чтобы работать правильно. Он записывает байты в выходной буфер. Возможно, что методы, использующие писатель, как 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);
        }
    }
}

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

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

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

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

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

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

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

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

    }

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

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

его можно использовать для другой цели задачи также.

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

вот модифицированная версия выше:

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

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

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

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

недавно я столкнулся с той же проблемой, вы можете проверить мой код: Я установил его для одного # на 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();
}
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();
    }
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");
    }
}