У меня есть программа Java, работающая в режиме командной строки. Я хотел бы отобразить индикатор выполнения, показывающий процент выполненной работы. Такой же индикатор прогресса, который вы увидите с помощью wget под unix. Возможно ли это?Строка выполнения командной строки в Java
ответ
Я уже реализовал этот вид вещей. Это не столько о Java, сколько о том, какие персонажи отправлять на консоль.
Ключ является разницей между \n
и \r
. \n
переходит в начало новой линии. Но \r
всего лишь возврат каретки - он возвращается к началу той же линии.
Так что нужно сделать, чтобы напечатать ваш прогресс бар, например, путем печати Строки
"|======== |\r"
На следующем тике индикатора выполнения, перезаписать ту же линию с более баром. (Потому что мы используем \ г, мы остаемся на той же линии) Например:
"|========= |\r"
То, что вы должны помнить, чтобы сделать, это когда сделано, если вы потом просто распечатать
"done!\n"
Вы может по-прежнему иметь мусор из индикатора выполнения на линии. Поэтому после того, как вы закончите работу с индикатором выполнения, обязательно напечатайте достаточно пробелов, чтобы удалить его из строки. Такие как:
"done |\n"
Надеюсь, что это поможет.
Несомненно помогает. Большое спасибо. –
Действительно ли это кросс-платформенный? Вероятно, он будет нормально работать в Windows и Linux, но как насчет Mac? У меня его нет, поэтому я не могу попробовать ... –
@RaduMurzea OS X - это ОС NIX, поэтому, если она работает в Linux, она будет работать на OS X (это не так для всех, но это правда). – bfontaine
Это возможно с помощью библиотеки Java Curses. This - это то, что я нашел. Я не использовал его сам, и я не знаю, является ли это кросс-платформенным.
Проклятия могут быть немного накладными расходами для удобного использования, в котором я нуждаюсь, но это наверняка трек. Благодарю. –
C# Пример, но я предполагаю, что это то же самое для System.out.print
в Java. Не стесняйтесь исправлять меня, если я ошибаюсь.
В принципе, вы хотите записать escape-символ \r
в начало вашего сообщения , что приведет к возврату курсора к началу строки (подача строки) без перехода на следующую строку.
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();
}
Приятный пример, обязательно будет полезен. Благодарю. –
Красивая! Спасибо. Работает как заклинатель. Легко читается. Lovely –
Я нашел следующий код для правильной работы. Он записывает байты в выходной буфер. Возможно, что методы с использованием писателя, такие как метод 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);
}
}
}
Я использую «прыгающий» индикатор выполнения, когда мне нужно отложить инструмент, чтобы предотвратить состояние гонки.
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");
}
Вот модифицированная версия выше:
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 ...");
Это хороший пример многопоточности! Очень полезно. – user7185318
Я проделал определенный процентный прогресс, чтобы проверить оставшийся файл загрузки.
Я периодически вызываю метод в своем файле, чтобы проверить общий размер файла и оставить его и оставить в %
.
Его можно использовать и для других целей.
Тест и выход Пример
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");
}
}
while (true) {
System.out.write(("\r" + System.currentTimeMillis()).getBytes());
Thread.sleep(1000);
}
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();
}
Я недавно столкнулся с такой же проблемой, вы можете проверить мой код: Я установил его для одного # на 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();
}
Существует https://github.com/ctongfei/progressbar, Лицензия: MIT
Простой прогресс консоли бар. Запись строки выполнения теперь выполняется в другом потоке.
Менло, Fira Mono, Source Code 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
Я не знаю ответа на Ваш вопрос, но вы могли бы начать с проверки библиотек, упомянутых в этом вопросе : http://stackoverflow.com/questions/435740/are-there-good-java-libraries-that-facilitate-building-command-line-applications – Jonik
Спасибо. В цитированных библиотеках больше говорится о синтаксическом анализе аргументов командной строки, а не отображении в консоли. Но спасибо в любом случае. –
Это по теме. OP спрашивает, если это возможно, а не для рекомендации библиотеки (по крайней мере, в текущем редактировании) –