Tôi có một chương trình Java đang chạy trong chế độ dòng lệnh. Tôi muốn hiển thị một thanh tiến trình, hiển thị phần trăm công việc được thực hiện. Loại thanh tiến trình tương tự bạn sẽ thấy bằng cách sử dụng wget dưới unix. Điều này có thể không?
Tôi có một chương trình Java đang chạy trong chế độ dòng lệnh. Tôi muốn hiển thị một thanh tiến trình, hiển thị phần trăm công việc được thực hiện. Loại thanh tiến trình tương tự bạn sẽ thấy bằng cách sử dụng wget dưới unix. Điều này có thể không?
Câu trả lời:
Tôi đã thực hiện loại điều này trước đây. Nó không quá nhiều về java, nhưng những nhân vật để gửi đến giao diện điều khiển.
Điều quan trọng là sự khác biệt giữa \n
và \r
.
\n
đi đến bắt đầu của một dòng mới. Nhưng \r
chỉ là trở về vận chuyển - nó trở lại bắt đầu của cùng một dòng.
Vì vậy, điều cần làm là in thanh tiến trình của bạn, ví dụ, bằng cách in chuỗi
"|======== |\r"
Trên đánh dấu tiếp theo của thanh tiến trình, ghi đè lên cùng một dòng với một thanh dài hơn. (vì chúng tôi đang sử dụng \ r, chúng tôi vẫn ở trên cùng một dòng) Ví dụ:
"|========= |\r"
Những gì bạn phải nhớ, là khi hoàn thành, nếu bạn chỉ cần in
"done!\n"
Bạn vẫn có thể có một số rác từ thanh tiến trình trên dòng. Vì vậy, sau khi bạn hoàn thành thanh tiến trình, hãy nhớ in đủ khoảng trắng để xóa nó khỏi dòng. Nhu la:
"done |\n"
Mong rằng sẽ giúp.
Có https://github.com/ctongfei/proTHERbar , Giấy phép: MIT
Thanh tiến trình điều khiển đơn giản. Tiến trình viết thanh bây giờ chạy trên một chủ đề khác.
Menlo, Fira Mono, Source Code Pro hoặc SF Mono được khuyến nghị cho các hiệu ứng hình ảnh tối ưu.
Đối với các phông chữ Consolas hoặc Andale Mono, hãy sử dụng ProgressBarStyle.ASCII
(xem bên dưới) vì các glyph vẽ hình hộp không được căn chỉnh chính xác trong các phông chữ này.
Maven:
<dependency>
<groupId>me.tongfei</groupId>
<artifactId>progressbar</artifactId>
<version>0.5.5</version>
</dependency>
Sử dụng:
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()
các cuộc gọi)? Có phải thư viện của bạn chạy không đồng bộ, do đó cho phép đồng hồ cập nhật? Nếu thư viện của tôi chạy trong nhiều ngày thì sao? Liệu nó có sử dụng /r
chiến lược? Điều đó sẽ dẫn đến sản lượng hàng trăm megabyte?
Tôi tìm thấy đoạn mã sau để hoạt động chính xác. Nó ghi byte vào bộ đệm đầu ra. Có lẽ rằng phương pháp sử dụng một nhà văn như System.out.println()
phương pháp thay thế xuất hiện của \r
để \n
cho phù hợp với dòng mẹ đẻ của mục tiêu kết thúc (nếu không được cấu hình đúng cách).
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);
}
}
}
Tôi đã thực hiện một phần trăm tiến độ trần để kiểm tra tệp tải xuống vẫn còn.
Tôi gọi phương thức định kỳ trong phần tải xuống tệp của mình để kiểm tra tổng kích thước tệp và phần còn lại và trình bày trong %
.
Nó có thể được sử dụng cho mục đích nhiệm vụ khác là tốt.
Ví dụ kiểm tra và đầu ra
progressPercentage(0, 1000);
[----------] 0%
progressPercentage(10, 100);
[*---------] 10%
progressPercentage(500000, 1000000);
[*****-----] 50%
progressPercentage(90, 100);
[*********-] 90%
progressPercentage(1000, 1000);
[**********] 100%
Kiểm tra với vòng lặp
for (int i = 0; i <= 200; i = i + 20) {
progressPercentage(i, 200);
try {
Thread.sleep(500);
} catch (Exception e) {
}
}
Phương pháp có thể dễ dàng sửa đổi:
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");
}
}
Ví dụ về C # nhưng tôi cho rằng điều này giống với System.out.print
trong Java. Hãy sửa tôi nếu tôi sai.
Về cơ bản, bạn muốn viết \r
ký tự thoát vào đầu tin nhắn của mình, điều này sẽ khiến con trỏ trở về đầu dòng (Nguồn cấp dữ liệu) mà không chuyển sang dòng tiếp theo.
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();
}
Một chút được tái cấu trúc và cập nhật phương thức @ maytham-'. Bây giờ, nó hỗ trợ một kích thước tùy ý của thanh tiến trình:
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");
}
}
Đây là một phiên bản sửa đổi ở trê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();
}
... và chính:
loading("Calculating ...");
Tôi sử dụng thanh tiến trình "nảy" khi tôi cần trì hoãn một công cụ để ngăn chặn tình trạng cuộc đua.
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");
}
Gần đây tôi đã gặp phải vấn đề tương tự, bạn có thể kiểm tra mã của mình: Tôi đã đặt nó cho một # trên 5%, mà bạn có thể sửa đổi sau này.
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();
}
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();
}
Tôi đã chỉnh sửa mã của Eoin Campbell thành java và thêm tiến trình được định dạng trong phần trăm.
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");
Và đầu ra:
Generating report...
[======== 24.2 % ]
[============ 45.5 % ]
[============ 78.8 % ===== ]
[============ 87.9 % ======== ]
[============ 100.0 % ============]
Successfully saved 32128 bytes
public class ProgressBar
{
private int max;
public ProgressBar(int max0) {
max = max0;
update(0);
}
public void update(int perc) {
String toPrint = "|";
for(int i = 0; i < max; i++) {
if(i <= (perc + 1))
toPrint += "=";
else
toPrint += " ";
}
if(perc >= max)
Console.print("\r");
else
Console.print(toPrint + "|\r");
}
}
public class Main {
public static void main(String[] args) throws Exception {
System.out.println("Loading : ");
int count =1;
for(int j=1;j<150;j++){
System.out.print("\r");
if(count==1){
System.out.print("/");
count++;
}
else if(count==2){
System.out.print("|");
count++;
}
else if(count==3){
System.out.print("-");
count++;
}
else if(count==4){
System.out.print("\\");
count++;
}
else if(count==5){
System.out.print("|");
count++;
}
else
count = 1;
Thread.sleep(200);
}
}
}
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()) + "]";
}