Java 中基于控制台的进度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1001290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Console based progress in Java
提问by Monster
Is there are easy way to implement a rolling percentage for a process in Java, to be displayed in the console? I have a percentage data type (double) I generated during a particular process, but can I force it to the console window and have it refresh, instead of just printing a new line for each new update to the percentage? I was thinking about pushing a cls and updating, because I'm working in a Windows environment, but I was hoping Java had some sort of built-in capability. All suggestions welcomed! Thanks!
是否有简单的方法可以在 Java 中实现进程的滚动百分比,以显示在控制台中?我有一个在特定过程中生成的百分比数据类型(double),但是我可以将它强制到控制台窗口并刷新它,而不是仅仅为百分比的每个新更新打印一个新行吗?我正在考虑推送 cls 和更新,因为我在 Windows 环境中工作,但我希望 Java 具有某种内置功能。欢迎所有建议!谢谢!
采纳答案by laalto
You can print a carriage return \r
to put the cursor back to the beginning of line.
您可以打印回车符\r
将光标放回行首。
Example:
例子:
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) {}
}
}
回答by Glen
回答by David Johnstone
I'm quite sure there is no way to change anything that the console has already printed because Java considers the console (standard out) to be a PrintStream.
我很确定没有办法更改控制台已经打印的任何内容,因为 Java 将控制台(标准输出)视为 PrintStream。
回答by Tom Jefferys
Don't know about anything built in to java itself, but you can use terminal control codes to do things like reposition the cursor. Some details here: http://www.termsys.demon.co.uk/vtansi.htm
不知道 java 本身内置的任何内容,但您可以使用终端控制代码来执行诸如重新定位光标之类的操作。这里有一些细节:http: //www.termsys.demon.co.uk/vtansi.htm
回答by Thejesh GN
Clear the console by running the os specific command and then print the new percentage
通过运行 os 特定命令清除控制台,然后打印新的百分比
回答by Tongfei Chen
回答by Mike Shauneu
I use following code:
我使用以下代码:
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);
}
回答by Elphara77
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;
}
}
回答by victorantunes
Late for the party, but here's an answer:
聚会迟到了,但这是一个答案:
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;
}
Remember to use System.out.print()
instead of System.out.println()
记得用System.out.print()
代替System.out.println()