IT

Java의 명령 행 진행률 표시 줄

lottoking 2020. 7. 13. 07:51
반응형

Java의 명령 행 진행률 표시 줄


단일 라인 모드에서 실행중인 Java 프로그램이 있습니다. 진행률 표시 줄을 표시하여 작업 비율을 표시하고 싶습니다. 유닉스에서 wget을 사용하는 것과 같은 종류의 진행률 표시 줄. 이게 가능해?


나는 이런 종류의 것을 구현했습니다. 그것은 자바에 관한 것이 아니라 콘솔에 보낼 문자입니다.

열쇠 열쇠 차이 \n\r. \n새로운 줄의 시작으로갑니다. 그러나 캐리지 리턴\r 일뿐 입니다. 같은 라인의 시작 부분으로 돌아갑니다.

따라서 인쇄해야 할 일은 예를 들어서 인쇄하여 진행률 표시 줄을 인쇄하는 것입니다.

"|========        |\r"

진행률 표시 줄의 다음 눈금에서 동일한 줄을 더 긴 막대로 자주 사용합니다. (\ r을 사용하고 있기 때문에 같은 줄을 유지합니다) 예를 들면 다음과 같습니다.

"|=========       |\r"

기억해야 할 일이 완료되면 인쇄 한 다음 인쇄하는 것입니다.

"done!\n"

회선의 진행률 표시 줄에 쓰레기가 남아있을 수 있습니다. 즉, 진행률 표시 줄을 다 사건은 공백을 인쇄하여 줄에서 제거하십시오. 같은 :

"done             |\n"

희망이 도움이됩니다.


https://github.com/ctongfei/progressbar : MIT

간단한 콘솔 진행 표시 줄. 진행률 표시 줄 쓰기가 이제 다른 프로그램에서 실행됩니다.

Menlo, Fira Mono, Source Code Pro 또는 SF Mono가 권장되는 시각 효과를 권장합니다.

Consolas 또는하는 Andale 모노 글꼴 의 경우 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

다음 코드가 의미한다는 것을 알았습니다. 출력 버퍼에 바이트를 씁니다. 메소드와 같은 아마도 라이터를 사용하는 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 (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 # 예제이지만 System.out.printJava는 동일 가정합니다 . 내가 틀렸다면 자유롭게 고쳐주세요.

기본적으로 \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 ...");

이것은 Java Curses 라이브러리에서 가능합니다. 이것이 내가 그것이 것입니다. 나는 그것을 직접 사용하지 않습니다.


경쟁 조건을 방지하기 위해 도구를 지연해야 할 때 "튀는"진행률 표시 줄을 사용합니다.

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");
}

나는 최근에 같은 문제에 직면했다, 당신은 내 코드를 확인할 수 있습니다 : 나는 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();
}

@ 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");
        }
    }

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();
    }

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);
        }

        }

    }

참고 URL : https://stackoverflow.com/questions/852665/command-line-progress-bar-in-java

반응형