Java中基于控制台的进度[重复]
Posted
技术标签:
【中文标题】Java中基于控制台的进度[重复]【英文标题】:Console based progress in Java [duplicate] 【发布时间】:2010-11-03 07:56:27 【问题描述】:是否有简单的方法可以在 Java 中实现进程的滚动百分比,以显示在控制台中?我有一个在特定过程中生成的百分比数据类型(双精度),但我可以将它强制到控制台窗口并刷新它,而不是为每个新的百分比更新打印一个新行吗?我正在考虑推送 cls 和更新,因为我在 Windows 环境中工作,但我希望 Java 具有某种内置功能。欢迎所有建议!谢谢!
【问题讨论】:
作为记录,一个密切相关的旧问题:***.com/questions/852665/… 【参考方案1】:您可以打印回车\r
将光标放回行首。
例子:
public class ProgressDemo
static void updateProgress(double progressPercentage)
final int width = 50; // progress bar width in chars
System.out.print("\r[");
int i = 0;
for (; i <= (int)(progressPercentage*width); i++)
System.out.print(".");
for (; i < width; i++)
System.out.print(" ");
System.out.print("]");
public static void main(String[] args)
try
for (double progressPercentage = 0.0; progressPercentage < 1.0; progressPercentage += 0.01)
updateProgress(progressPercentage);
Thread.sleep(20);
catch (InterruptedException e)
【讨论】:
我刚试过。它不起作用。 (在 Eclipse 中测试。) @David Johnstone:上面的例子至少在传统的控制台窗口中有效。 @laalto:是的,在普通控制台窗口中尝试过,对我有用。 漂亮!我一定要记住这个! 哦,哇,对不起。我也在 Eclipse 中尝试过,只是假设它向下滚动了整个页面。优秀!谢谢!【参考方案2】:我使用以下代码:
public static void main(String[] args)
long total = 235;
long startTime = System.currentTimeMillis();
for (int i = 1; i <= total; i = i + 3)
try
Thread.sleep(50);
printProgress(startTime, total, i);
catch (InterruptedException e)
private static void printProgress(long startTime, long total, long current)
long eta = current == 0 ? 0 :
(total - current) * (System.currentTimeMillis() - startTime) / current;
String etaHms = current == 0 ? "N/A" :
String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(eta),
TimeUnit.MILLISECONDS.toMinutes(eta) % TimeUnit.HOURS.toMinutes(1),
TimeUnit.MILLISECONDS.toSeconds(eta) % TimeUnit.MINUTES.toSeconds(1));
StringBuilder string = new StringBuilder(140);
int percent = (int) (current * 100 / total);
string
.append('\r')
.append(String.join("", Collections.nCopies(percent == 0 ? 2 : 2 - (int) (Math.log10(percent)), " ")))
.append(String.format(" %d%% [", percent))
.append(String.join("", Collections.nCopies(percent, "=")))
.append('>')
.append(String.join("", Collections.nCopies(100 - percent, " ")))
.append(']')
.append(String.join("", Collections.nCopies(current == 0 ? (int) (Math.log10(total)) : (int) (Math.log10(total)) - (int) (Math.log10(current)), " ")))
.append(String.format(" %d/%d, ETA: %s", current, total, etaHms));
System.out.print(string);
结果:
【讨论】:
哇!谢谢!对我来说,工作真的很好,比标记的答案更好。 请注意,如果您以i=0
开始 for 循环,那么您可能会从此代码中获得 IllegalArgumentException。否则会产生魅力。
这对我来说似乎无法正常工作。我完全复制了它,而不是进度条保持在同一行,而是为每个打印新行。
它可能发生在 IDE(eclipse、idea)中尝试在终端中
这在 Windows 10 上的 cmd 中不起作用。【参考方案3】:
我用 Java 写过这样的包。
https://github.com/ctongfei/progressbar
【讨论】:
对于那些想知道的人:它也支持 Mac Terminal。 很棒的库!谢谢【参考方案4】:我认为没有内置功能可以满足您的需求。
有一个库可以做到这一点(JLine)。
看到这个tutorial
【讨论】:
【参考方案5】:我很确定无法更改控制台已经打印的任何内容,因为 Java 将控制台(标准输出)视为 PrintStream。
【讨论】:
【参考方案6】:不知道 Java 本身内置的任何内容,但您可以使用终端控制代码来执行诸如重新定位光标之类的操作。这里有一些细节:http://www.termsys.demon.co.uk/vtansi.htm
【讨论】:
【参考方案7】:通过运行特定于操作系统的命令清除控制台,然后打印新的百分比
【讨论】:
【参考方案8】:import java.util.Random;
public class ConsoleProgress
private static String CURSOR_STRING = "0%.......10%.......20%.......30%.......40%.......50%.......60%.......70%.......80%.......90%.....100%";
private static final double MAX_STEP = CURSOR_STRING.length() - 1;
private double max;
private double step;
private double cursor;
private double lastCursor;
public static void main(String[] args) throws InterruptedException
// ---------------------------------------------------------------------------------
int max = new Random().nextInt(400) + 1;
// ---------------------------------------------------------------------------------
// Example of use :
// ---------------------------------------------------------------------------------
ConsoleProgress progress = new ConsoleProgress("Progress (" + max + ") : ", max);
for (int i = 1; i <= max; i++, progress.nextProgress())
Thread.sleep(3L); // a task with no prints
public ConsoleProgress(String title, int maxCounts)
cursor = 0.;
max = maxCounts;
step = MAX_STEP / max;
System.out.print(title);
printCursor();
nextProgress();
public void nextProgress()
printCursor();
cursor += step;
private void printCursor()
int intCursor = (int) Math.round(cursor) + 1;
System.out.print(CURSOR_STRING.substring((int) lastCursor, intCursor));
if (lastCursor != intCursor && intCursor == CURSOR_STRING.length())
System.out.println(); // final print
lastCursor = intCursor;
【讨论】:
这显示在 Java 控制台的单行中 以及进入 Eclipse 控制台【参考方案9】:聚会迟到了,但这里有一个答案:
public static String getSingleLineProgress(double progress)
String progressOutput = "Progress: |";
String padding = Strings.padEnd("", (int) Math.ceil(progress / 5), '=');
progressOutput += Strings.padEnd(padding, 0, ' ') + df.format(progress) + "%|\r";
if (progress == 100.0D)
progressOutput += "\n";
return progressOutput;
记得使用System.out.print()
而不是System.out.println()
【讨论】:
以上是关于Java中基于控制台的进度[重复]的主要内容,如果未能解决你的问题,请参考以下文章
Jupyter Notebook 中的 tqdm 重复打印新的进度条
C语言中如何控制只在某一个位置打印?比如进度百分比数字的显示。