我有一个在命令行模式下运行的Java程序,我想显示一个进度条,显示作业完成的百分比。和unix系统下使用wget看到的同样类型的进度条一样。这可能吗?
我有一个在命令行模式下运行的Java程序,我想显示一个进度条,显示作业完成的百分比。和unix系统下使用wget看到的同样类型的进度条一样。这可能吗?
"|======== |\r"
在下一个进度条的时钟周期内,使用更长的进度条覆盖相同的行。(因为我们使用\r,所以保持在同一行)。例如:"|========= |\r"
你需要记住的是,在完成后,如果你只是打印
"done!\n"
你的行可能仍然存在进度条的垃圾信息。因此,在使用完进度条后,请确保打印足够的空格以将其从行中移除。例如:
"done |\n"
System.out.print();
而不是标准的 #println
。但是其中的缺点是,我必须在完成/使用进度条后加入一个 #println
,否则它会消失! - JumperBot_这里有一个简单的控制台进度条:https://github.com/ctongfei/progressbar,许可证:MIT。
现在进度条的编写在另一个线程上运行。
建议使用Menlo、Fira Mono、Source Code Pro或SF Mono字体以获得最佳视觉效果。
对于Consolas或Andale Mono字体,请使用ProgressBarStyle.ASCII
(见下文),因为在这些字体中,绘制框图的字形未对齐。
<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
step()
调用之间的分钟数)之间运行几分钟怎么办?你的库是否异步运行,从而允许时钟更新?如果我的库运行了几天怎么办?它是否使用/r
策略?这会导致多达几百兆字节的输出吗? - Groostav我发现以下代码能够正常工作。它将字节写入输出缓冲区。也许使用类似 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);
}
}
}
我已经做了一个百分比进度条,用于检查剩余下载文件。
我会定期调用这个方法,在文件下载过程中检查总文件大小和剩余量,并以 %
的形式呈现出来。
它也可以用于其他任务目的。
测试和输出示例
progressPercentage(0, 1000);
[----------] 0%
progressPercentage(10, 100);
[*---------] 10%
progressPercentage(500000, 1000000);
[*****-----] 50%
progressPercentage(90, 100);
[*********-] 90%
progressPercentage(1000, 1000);
[**********] 100%
用 for 循环测试
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");
}
}
这个C#示例我认为在Java中的System.out.print
也是一样的。如果我错了,请随意纠正。
基本上,您需要在消息的开头写出\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();
}
对 @maytham-ɯɐɥʇʎɐɯ 的方法进行了微调和更新,现在它支持任意大小的进度条:
public static void progressPercentage(int done, int total) {
int size = 5;
String iconLeftBoundary = "[";
String iconDone = "=";
String iconRemain = ".";
String iconRightBoundary = "]";
if (done > total) {
throw new IllegalArgumentException();
}
int donePercents = (100 * done) / total;
int doneLength = size * donePercents / 100;
StringBuilder bar = new StringBuilder(iconLeftBoundary);
for (int i = 0; i < size; i++) {
if (i < doneLength) {
bar.append(iconDone);
} else {
bar.append(iconRemain);
}
}
bar.append(iconRightBoundary);
System.out.print("\r" + bar + " " + donePercents + "%");
if (done == total) {
System.out.print("\n");
}
}
我将Eoin Campbell的代码转换成了Java,并添加了格式化的进度百分比。
public static String progressBar(int currentValue, int maxValue) {
int progressBarLength = 33; //
if (progressBarLength < 9 || progressBarLength % 2 == 0) {
throw new ArithmeticException("formattedPercent.length() = 9! + even number of chars (one for each side)");
}
int currentProgressBarIndex = (int) Math.ceil(((double) progressBarLength / maxValue) * currentValue);
String formattedPercent = String.format(" %5.1f %% ", (100 * currentProgressBarIndex) / (double) progressBarLength);
int percentStartIndex = ((progressBarLength - formattedPercent.length()) / 2);
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int progressBarIndex = 0; progressBarIndex < progressBarLength; progressBarIndex++) {
if (progressBarIndex <= percentStartIndex - 1
|| progressBarIndex >= percentStartIndex + formattedPercent.length()) {
sb.append(currentProgressBarIndex <= progressBarIndex ? " " : "=");
} else if (progressBarIndex == percentStartIndex) {
sb.append(formattedPercent);
}
}
sb.append("]");
return sb.toString();
}
int max = 22;
System.out.println("Generating report...");
for (int i = 0; i <= max; i++) {
Thread.sleep(100);
System.out.print(String.format("\r%s", progressBar(i, max)));
}
System.out.println("\nSuccessfully saved 32128 bytes");
输出:
Generating report...
[======== 24.2 % ]
[============ 45.5 % ]
[============ 78.8 % ===== ]
[============ 87.9 % ======== ]
[============ 100.0 % ============]
Successfully saved 32128 bytes
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");
}
}
}
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 ...");
我最近也遇到了同样的问题,你可以查看我的代码: 我将其设置为一个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();
}