如何删除 System.out.println()打印到控制台的内容?

在 Java 应用程序中,我使用了一些对 System.out.println()的调用。现在我想找到一种方法,通过编程方式删除这些内容。

我找不到任何解决方案与谷歌,所以有任何提示?

244470 次浏览

System.outPrintStream,它本身不提供任何方法来修改输出内容。根据支持该对象的内容,您可能能够修改它,也可能不能够修改它。例如,如果将 System.out重定向到一个日志文件,则可以在事后修改该文件。如果文本直接进入控制台,那么当文本到达控制台缓冲区的顶部时,文本就会消失,但是没有办法通过编程方式对其进行处理。

我不确定您到底希望完成什么,但是您可以考虑创建一个代理 PrintStream来在消息输出时过滤它们,而不是在事后删除它们。

Java 中不支持清除屏幕,但是您可以尝试一些技巧来实现这一点。

A)使用与操作系统相关的命令,比如 Windows:

Runtime.getRuntime().exec("cls");

b) Put bunch of new lines (this makes ilusion that screen is clear)

c) If you ever want to turn off System.out, you can try this:

System.setOut(new PrintStream(new OutputStream() {
@Override public void write(int b) throws IOException {}
}));

您可以打印退格字符 \b,其次数与以前打印的字符相同。

System.out.print("hello");
Thread.sleep(1000); // Just to give the user a chance to see "hello".
System.out.print("\b\b\b\b\b");
System.out.print("world");

注意: 在 Mars (4.5)之前的旧版本中,这在 Eclipse 控制台中并不能完美地工作。然而,这在命令控制台中完全可以正常工作。参见 如何让后退空间 b 工作在 Eclipse 的控制台?

为了补充 BalusC 的答案..。

重复调用带有延迟的 System.out.print("\b \b")会产生与在{ Windows7命令控制台/Java1.6}中回退时完全相同的行为

我正在使用 BlueJ 进行 Java 编程。有一种方法可以清除它的终端窗口的屏幕。试试这个:-

System.out.print ('\f');

这将清除在这一行之前打印的任何内容。但是这在命令提示符中不起作用。

要清除 Output 屏幕,可以模拟一个真人按 CTRL + L(清除输出)。你可以通过使用 Robot ()类来实现这一点,下面是如何做到这一点:

try {
Robot robbie = new Robot();
robbie.keyPress(17); // Holds CTRL key.
robbie.keyPress(76); // Holds L key.
robbie.keyRelease(17); // Releases CTRL key.
robbie.keyRelease(76); // Releases L key.
} catch (AWTException ex) {
Logger.getLogger(LoginPage.class.getName()).log(Level.SEVERE, null, ex);
}

我成功地使用了以下方法:

@Before
public void dontPrintExceptions() {
// get rid of the stack trace prints for expected exceptions
System.setErr(new PrintStream(new NullStream()));
}

NullStream位于 import com.sun.tools.internal.xjc.util包中,因此可能不能在所有 Java 实现中使用,但它只是一个 OutputStream,应该足够简单,可以编写自己的。

您可以使用光标向上删除一行,并擦除文本,或者只是用新文本覆盖旧文本。

int count = 1;
System.out.print(String.format("\033[%dA",count)); // Move up
System.out.print("\033[2K"); // Erase line content

or clear screen

System.out.print(String.format("\033[2J"));

这是标准操作系统,但是根据维基百科的说法,Windows 控制台并不遵循这个标准。

看看: http://www.termsys.demon.co.uk/vtansi.htm

我在 EclipseIDE 中找到了清除控制台的解决方案。它使用 Robot 类。请参阅下面的代码和说明:

   import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;


public void wipeConsole() throws AWTException{
Robot robbie = new Robot();
//shows the Console View
robbie.keyPress(KeyEvent.VK_ALT);
robbie.keyPress(KeyEvent.VK_SHIFT);
robbie.keyPress(KeyEvent.VK_Q);
robbie.keyRelease(KeyEvent.VK_ALT);
robbie.keyPress(KeyEvent.VK_SHIFT);
robbie.keyPress(KeyEvent.VK_Q);
robbie.keyPress(KeyEvent.VK_C);
robbie.keyRelease(KeyEvent.VK_C);


//clears the console
robbie.keyPress(KeyEvent.VK_SHIFT);
robbie.keyPress(KeyEvent.VK_F10);
robbie.keyRelease(KeyEvent.VK_SHIFT);
robbie.keyRelease(KeyEvent.VK_F10);
robbie.keyPress(KeyEvent.VK_R);
robbie.keyRelease(KeyEvent.VK_R);
}

假设您没有更改 Eclipse 中的默认热键设置并导入那些 Java 类,那么这应该可以工作。

最简单的方法是:

System.out.println("\f");


System.out.println("\u000c");

我发现,在 Eclipse Mars 中,如果你可以安全地假设你用来替换它的那一行至少和你正在擦除的那一行一样长,那么简单地打印’r’(回车符)就可以让你的光标移回到那一行的开头,覆盖你看到的任何字符。我想如果新的线更短,你可以用空格来弥补不同。

对于实时更新进度百分比,这种方法在 eclipse 中非常方便,例如在我从一个程序中删除的代码片段中。这是一个从网站下载媒体文件的程序的一部分。

    URL url=new URL(link);
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
connection.connect();
if(connection.getResponseCode()!=HttpURLConnection.HTTP_OK)
{
throw new RuntimeException("Response "+connection.getResponseCode()+": "+connection.getResponseMessage()+" on url "+link);
}
long fileLength=connection.getContentLengthLong();
File newFile=new File(ROOT_DIR,link.substring(link.lastIndexOf('/')));
try(InputStream input=connection.getInputStream();
OutputStream output=new FileOutputStream(newFile);)
{
byte[] buffer=new byte[4096];
int count=input.read(buffer);
long totalRead=count;
System.out.println("Writing "+url+" to "+newFile+" ("+fileLength+" bytes)");
System.out.printf("%.2f%%",((double)totalRead/(double)fileLength)*100.0);
while(count!=-1)
{
output.write(buffer,0,count);
count=input.read(buffer);
totalRead+=count;
System.out.printf("\r%.2f%%",((double)totalRead/(double)fileLength)*100.0);
}
System.out.println("\nFinished index "+INDEX);
}

BalusC answer didn't work for me (bash console on Ubuntu). Some stuff remained at the end of the line. So I rolled over again with spaces. Thread.sleep() is used in the below snippet so you can see what's happening.

String foo = "the quick brown fox jumped over the fence";
System.out.printf(foo);
try {Thread.sleep(1000);} catch (InterruptedException e) {}
System.out.printf("%s", mul("\b", foo.length()));
try {Thread.sleep(1000);} catch (InterruptedException e) {}
System.out.printf("%s", mul(" ", foo.length()));
try {Thread.sleep(1000);} catch (InterruptedException e) {}
System.out.printf("%s", mul("\b", foo.length()));

其中 mul是一个简单的方法,定义如下:

private static String mul(String s, int n) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < n ; i++)
builder.append(s);
return builder.toString();
}

(番石榴丝类也提供了类似的 repeat方法)

在 BlueJ 中有两种不同的方法来清除终端。您可以让 BlueJ 在每次交互式方法调用之前自动清除终端。为此,在终端的“选项”菜单中激活“清除方法调用屏幕”选项。还可以在程序内以编程方式清除终端。打印一个 formfeed 字符(Unicode 000C)会清除 BlueJ 终端,例如:

System.out.print('\u000C');

对于智能控制台的 0x08字符为我工作!

System.out.print((char) 8);

this solution is applicable if you want to remove some System.out.println() output. It restricts that output to print on console and print other outputs.

PrintStream ps = System.out;
System.setOut(new PrintStream(new OutputStream() {
@Override
public void write(int b) throws IOException {}
}));


System.out.println("It will not print");


//To again enable it.
System.setOut(ps);


System.out.println("It will print");