コマンド ライン モードで Java プログラムを実行しています。完了した作業のパーセンテージを示す進行状況バーを表示したいと思います。UNIX で wget を使用して表示されるのと同じ種類のプログレス バーです。これは可能ですか?
17 に答える
私は以前にこの種のことを実装しました。Javaについてではなく、コンソールに送信する文字についてです。
\n
鍵はとの違い\r
です。
\n
新しい行の先頭に移動します。しかし、これ\r
はただのキャリッジ リターンです。同じ行の先頭に戻ります。
したがって、たとえば文字列を印刷して、プログレスバーを印刷する必要があります
"|======== |\r"
プログレス バーの次の目盛りで、同じ行をより長いバーで上書きします。(\r を使用しているため、同じ行にとどまります) 例:
"|========= |\r"
あなたがしなければならないことは、完了したら、印刷するだけです
"done!\n"
行の進行状況バーからのゴミがまだ残っている可能性があります。したがって、進行状況バーの処理が完了したら、行から削除するのに十分な空白を出力してください。そのような:
"done |\n"
それが役立つことを願っています。
次のコードが正しく動作することがわかりました。出力バッファにバイトを書き込みます。おそらく、メソッドのようなライターを使用するメソッドは、ターゲットのネイティブ行末に一致するように to の出現を置き換えます (適切に構成されていない場合) 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);
}
}
}
System.out.print
C#の例ですが、これはJavaでも同じだと思います。私が間違っている場合は、遠慮なく訂正してください。
基本的に、メッセージの先頭にエスケープ文字を書き出す\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();
}
上記の修正版は次のとおりです。
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 ...");
これは、JavaCursesライブラリで可能になります。これは私が見つけたものです。私はそれを自分で使用したことがなく、クロスプラットフォームかどうかもわかりません。
static String progressBar(int progressBarSize, long currentPosition, long startPositoin, long finishPosition) {
String bar = "";
int nPositions = progressBarSize;
char pb = '░';
char stat = '█';
for (int p = 0; p < nPositions; p++) {
bar += pb;
}
int ststus = (int) (100 * (currentPosition - startPositoin) / (finishPosition - startPositoin));
int move = (nPositions * ststus) / 100;
return "[" + bar.substring(0, move).replace(pb, stat) + ststus + "%" + bar.substring(move, bar.length()) + "]";
}
複雑である必要はありません。
public class Demo {
private static final StringBuilder sb = new StringBuilder();
public static void main (String[] args) throws java.lang.Exception
{
for (int i = 0 ; i <= 100 ; i++) {
sb.setLength(0);
for (int j = 0 ; j < i; j++) {
sb.append("#");
}
Thread.sleep(100);
System.out.print("[" + String.format("%-100s", sb.toString()) + "] " + i + "%");
System.out.print("\r");
}
}
}
public class ConsoleApp {
static String DisplayBar(int i)
{
StringBuilder sb = new StringBuilder();
int x = i / 2;
sb.append("|");
for (int k = 0; k < 50; k++)
sb.append(String.format("%s", ((x <= k) ? " " : "=")));
sb.append("|");
return sb.toString();
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i <= 100; i++)
{
Thread.sleep(200);
System.out.printf("\r%s %s Done", DisplayBar(i), i);
}
}
}