添加带有进度的加载效果

Add a loading effect with progress

通常当我们使用终端或命令提示符下载东西时,我们会得到这样的进度:

----------10%

after a while

------------------------------------------33%

after a while

---------------------------------------------------------48%

然后这一直持续到它在同一行中达到 100%。即使我尝试做这样的事情,但最终得到这样的结果:

-1%-2%-3%-4%-5%-6%-7%-8%-9%-10%-11%-12%-13%-14%-15%-16%-17%-18%-19%-20%-21%-22%-23%-24%-25%-26%-27%-28%-29%-30%-31%-32%-33%-34%-35%-36%-37%-38%-39%-40%-41%-42%-43%-44%-45%-46%-47%-48%-49%-50%-51%-52%-53%-54%-55%-56%-57%-58%-59%-60%-61%-62%-63%-64%-65%-66%-67%-68%-69%-70%-71%-72%-73%-74%-75%-76%-77%-78%-79%-80%-81%-82%-83%-84%-85%-86%-87%-88%-89%-90%-91%-92%-93%-94%-95%-96%-97%-98%-99%-100%

因此,每次进步后都会发生这种情况。这就是我这样做的目的:

for (progress in 1..100){
   print("-$progress%")
   Thread.sleep(100)
}

或 java:

for(int i = 0; i < 100; i++){
   System.out.print("-" + i + "%");
}

那么,我怎样才能在一行中取得这样的进展呢?

我可以回答 Java。

假设您希望每个进度打印在一个新行上,请使用: System.out.println(); 代替。或在相关处添加 \n

还假设你想随着每个增量进度点增加破折号的数量,你必须添加一个内部 for 循环来多次重复打印“-”,像这样?

for (int i = 0; i < 100; i++) {
    TimeUnit.SECONDS.sleep(1);
    for (int j = 0; j < i; j++) {
        System.out.print("-");
    }
    System.out.print(i + "%\n");
}

Example output

或者如果你想让它看起来像是在清除线条然后重新打印新的进度条,让它看起来动态,你可以尝试这样的事情(添加或多或少的 \n 字符来增加或减少间隙):

for (int i = 0; i < 100; i++) {
    TimeUnit.SECONDS.sleep(1);
    System.out.print("\n\n\n\n\n\n\n\n\n\n\n\n\n");
    for (int j = 0; j < i; j++) {
        System.out.print("-");
    }
    System.out.print(i + "%\n");
}

如果你想在一行中不间断地显示加载栏,你可以尝试使用这种方法:

        for (int i = 1; i <= 100; i++) {
            Thread.sleep(300);
            String backspaceCharacter = "\b";

            int numberOfCharactersToDelete =  2;
            if (i / 10 > 0) numberOfCharactersToDelete++;
            System.out.print(backspaceCharacter.repeat(numberOfCharactersToDelete) + "-" + i + "%");
        }

它的工作原理是打印一个退格字符来删除前面的 x%。肯定有更好的方法可以做到这一点,但我发现这种方法是最简单的。 警告:我没有对此进行错误检查,它应该更像是一种灵感,而不是一个完整的解决方案。它也可能不适用于某些控制台。

在这里尝试这个字符串重复 n 次,然后打印它及其覆盖的百分比。

"\r" 是一个转义序列,它将光标带回当前行的起点。

import java.lang.Thread;

class Main {
    public static void main(String args[]) {
        try {
            for (int i = 0; i <= 100; i++) {
                System.out.print("\r" + "-".repeat(i) + i + "%");
                Thread.sleep(50); // 50 millisecond
            }
            System.out.println();
        } catch (Exception e) {
            System.err.println(e);
        }
    }
}

这是科特林代码:

fun main() {
    for( i in 1..100 ){
       print("\r ${"=".repeat(i)}> $i%");
       Thread.sleep(50);
    }
    println()
}

输出JAVA:

KOTLIN 输出:

如其他答案所示,一般来说 简单的方法是打印一个没有换行符的回车 return (\r) (\n):这会将光标移回同一行的开头,之后您可以用新行覆盖现有行。

这仅在新版本的行至少与前一版本一样长时才有效——或者您附加空格以覆盖其余部分。

如果你想做更强大的事情,通常的方法是打印ANSI escape codes。大多数现代终端程序都能理解这些;它们让您可以将光标直接移动到 window 中的任意点,清除一行甚至整个屏幕,并使用颜色和效果,例如粗体、斜体和反转视频。

(传统上,您必须确定当前的终端类型,然后在 termcap 数据库中查找它支持的转义序列 — 但如今,除非您需要最大的兼容性,否则这就太过分了,而且ANSI 转义得到很好的支持。)

或者,您可以使用一个库,它可以为您完成所有这些工作;参见 this question