java - por - Ocultar System.out.print llamadas de una clase
ingresar numeros por teclado en java (5)
Cambie PrintStream original con uno ficticio que no haga nada con su método write()
.
No olvide reemplazar el PrintStream original cuando haya terminado.
System.out.println("NOW YOU CAN SEE ME");
PrintStream originalStream = System.out;
PrintStream dummyStream = new PrintStream(new OutputStream(){
public void write(int b) {
// NO-OP
}
});
System.setOut(dummyStream);
System.out.println("NOW YOU CAN NOT");
System.setOut(originalStream);
System.out.println("NOW YOU CAN SEE ME AGAIN");
Estoy usando una biblioteca de java (archivo jar). El autor del archivo puso en un montón de System.out.print
y System.out.println
s. ¿Hay alguna forma de ocultar estos mensajes para un objeto en particular?
* EDITAR: Parece que el archivo jar parece estar creando un montón de subprocesos y cada subproceso tiene su propio System.out.println''s ...
Hay dos maneras en las que puedo pensar en hacer esto además de lo que se ha publicado anteriormente:
1. Use un decompilador de Java y elimine cada llamada de System.out
y vuelva a compilar el jar. Recomendaría este si eliges esta ruta.
2. Puede usar la traza de la pila para encontrar el tipo de llamada. (De ¿Cómo encuentro la persona que llama a un método usando stacktrace o reflexión? )
List<String> classNames = ...
final PrintStream originalOut = System.out;
PrintStream filterStream = new PrintStream(new OutputStream() {
public void write(int b) {
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
if(!classNames.contains(stackTraceElements[someNumber].getClassName()){
originalOut.write(b);
}
}
});
System.setOut(filterStream);
Donde classNames
es el nombre completo de cada clase en el archivo jar y someNumber
es el lugar correcto en la pila que debe estar viendo (probablemente 1 o 2).
/ e1
Después de algunas pruebas, creo que el número que necesitará para someNumber
es 10 u 11. Esto se debe a que System.out.print
no llama directamente al método de write
.
Ejemplo de seguimiento de pila para escribir h
:
(Las trazas de pila están en el índice, orden de obtener getMethodName
, obtener nombre de getMethodName
, orden obtener nombre de getMethodName
).
0 java.lang.Thread null getStackTrace
1 reflection.StackTrace$1 StackTrace.java write
2 java.io.OutputStream null write
3 java.io.PrintStream null write
4 sun.nio.cs.StreamEncoder null writeBytes
5 sun.nio.cs.StreamEncoder null implFlushBuffer
6 sun.nio.cs.StreamEncoder null flushBuffer
7 java.io.OutputStreamWriter null flushBuffer
8 java.io.PrintStream null write
9 java.io.PrintStream null print
10 java.io.PrintStream null println
11 reflection.StackTrace StackTrace.java main
Ejemplo de seguimiento de pila para escribir /n
:
0 java.lang.Thread null getStackTrace
1 reflection.StackTrace$1 StackTrace.java write
2 java.io.OutputStream null write
3 java.io.PrintStream null write
4 sun.nio.cs.StreamEncoder null writeBytes
5 sun.nio.cs.StreamEncoder null implFlushBuffer
6 sun.nio.cs.StreamEncoder null flushBuffer
7 java.io.OutputStreamWriter null flushBuffer
8 java.io.PrintStream null newLine
9 java.io.PrintStream null println
10 reflection.StackTrace StackTrace.java main
reflection.StackTrace
es la clase principal que estoy usando para hacer la prueba. reflection.StackTrace$1
es mi filterStream
y estoy llamando a System.out.println
desde el método main
en reflection.StackTrace
.
/ e2
Esta 11 o 10 discrepancia parece ser porque println
calls print
y newLine
. print
pasa a call write
mientras newLine
escribe directamente el nuevo carácter de línea en la secuencia. Pero esto no debería importar ya que el archivo jar no contendrá java.io.PrintStream
.
La solución de su pregunta está here.. en el método SysOutController.ignoreSysout();
Si tienes un programa más grande, considera algo como
public abstract class Output {
private static final PrintStream out = System.out;
private static final PrintStream dummy = new PrintStream(new OutputStream() {@Override public void write(int b){} });
private static boolean globalOutputOn = true;
public static void toggleOutput() {
System.setOut((globalOutputOn=!globalOutputOn)?dummy:out);
}
public static void toggleOutput(boolean on) {
globalOutputOn = on;
System.setOut(on?out:dummy);
}
}
Esto garantiza que se puede activar y desactivar la salida en diferentes clases, mientras se garantiza que la salida se pueda activar más tarde.
Tú, por ejemplo, lo usas llamando
toggleOutput(false)
al inicio de cada método y
toggleOutput(true)
al final de cada método.
System.setOut();
es probablemente lo que estás buscando
System.setOut(new PrintStream(new OutputStream() {
public void write(int b) {
// NO-OP
}
}));