2016-05-03 9 views
2

Ich habe eine InputStream, die zu Standout eines anderen Prozesses angefügt ist. Manchmal muss ich Daten aus dem Stream protokollieren und manchmal nicht. Selbst wenn mir die Ausgabe egal ist, muss ich sie trotzdem lesen, damit der andere Prozess wegen eines vollen Ausgabepuffers nicht blockiert. Ich verwende den folgenden Code, um selektiv den Ausgang log:Wie ignoriere ich alle Daten von einem InputStream, ohne statische Analyse-Tools auszulösen?

InputStream is = ...; 
boolean report = ...; 
InputStreamReader isr = new InputStreamReader(is); 
BufferedReader br = new BufferedReader(isr); 
if (report) { 
    String line = null; 
    while ((line = br.readLine()) != null) { 
     Debug.println(line); 
    } 
} else { 
    while (br.readLine() != null) { 
    } 
} 

jedoch in der zweiten while Schleife, FindBugs Benachrichtigungen (RV_DONT_JUST_NULL_CHECK_READLINE), die ich rufe readLine und nur prüft wird, ob es null ist, nichts zu tun mit das Ergebnis. Seine Analyse ist korrekt, aber ich möchte wollen nichts mit dem Ergebnis in diesem Fall tun. Gibt es eine idiomatische Methode, alle Daten aus einem Stream zu konsumieren und zu ignorieren, sodass FindBugs nicht wie ein Fehler aussieht?

Antwort

1

können Sie vermeiden String Objekte zu konstruieren, die die gerade weggeworfen erhalten durch skip auf dem InputStream verwenden. (InputStreamReader und BufferedReader haben auch skip Methoden, aber wenn Sie schauen, den gesamten Strom zu überspringen, werden Sie nicht wirklich brauchen, um die Zeichendecodierung Merkmale von InputStreamReader oder der Line-Erkennung und Puffer-Management-Funktionen von BufferedReader.)

while (is.skip(Long.MAX_VALUE) == Long.MAX_VALUE) { 
} 

Es ist unwahrscheinlich, dass die Schleife wird immer mehr als einmal laufen - Sie würden 8 Exabyte aus dem Stream lesen müssen zuerst - aber die Schleife gibt es eine andere FindBugs zu bezwingen Warnung (SR_NO_CHECKED), die, wenn Sie skip nennen geschieht ohne den Rückgabewert zu überprüfen.


die SuppressWarnings Anmerkung Mit dem Compiler ist unwirksam zum Schweigen zu bringen, weil es nicht die Compiler sind, die über den ungenutzten Rückgabewert besorgt sind. Die Annotation wird nicht im kompilierten Code gespeichert, daher können Bytecode-Analysatoren wie FindBugs sie nicht sehen. Darüber hinaus gilt in diesem Fall keine der Warnungen, die SuppressWarnings unterdrückt; insbesondere gilt unused nicht, da Rückgabewerte sind nicht unter den Dingen, die der Compiler überprüft.

Anstelle der integrierten Java-Funktion SuppressWarnings können Sie jedoch versuchen, einen anderen Unterdrückungsmechanismus zu verwenden, der von dem Tool zur statischen Analyse bereitgestellt wird, das die Warnung generiert. Im Fall von FindBugs ist dies die SuppressFBWarnings Annotation.

Um den Umfang der Unterdrückung von Warnungen zu minimieren, können Sie den Code zur Generierung von Warnungen in einer eigenen Methode isolieren. Zum Beispiel:

@SuppressFBWarnings("RV_DONT_JUST_NULL_CHECK_READLINE") 
private void consumeWholeStream(BufferedReader br) throws IOException { 
    while (br.readLine() != null) { 
    } 
} 

Dann können Sie diese Methode im gegebenen Kontext verwenden:

if (report) { 
    String line = null; 
    while ((line = br.readLine()) != null) { 
     Debug.println(line); 
    } 
} else { 
    consumeWholeStream(br); 
} 

Der Nachteil ist, dass dies die FindBugs Anmerkung jar auf Ihre Build-Abhängigkeiten hinzu. Es wird jedoch nicht zu den Laufzeit Abhängigkeiten des Programms hinzugefügt.

1

Versuchen Sie es mit der @SuppressWarnings-Notation.

prüfen Link Excluding warnings using @SuppressWarnings

Einige Hinweise dazu:.

„Ohne die Anmerkung, würde der Compiler beschweren sich, dass die lokale Variable s nie verwendet wird, mit der Anmerkung, der Compiler leise diese Warnung ignoriert lokal an die foo-Methode. Dies ermöglicht es, die Warnungen an anderen Orten der gleichen Übersetzungseinheit oder des gleichen Projekts zu behalten. "

+0

@SuppressWarnings ist anderen Lösungen überlegen, die Syntax-Tricks enthalten, um die Warnung zu schließen, weil es sich selbst dokumentiert: Sie sagen zukünftigen Lesern Ihres Codes (möglicherweise Sie selbst), dass Sie das tun wollten. – BadZen

+0

Aber @BadZen, sagt es nicht auch den Lesern, dass ich alle anderen möglichen Fehler in derselben Methode machen wollte, ob ich es tat oder nicht? Welche der möglichen 'SuppressWarns'-Kategorien empfiehlst du für meine Situation, Santiago? Keine der Links, auf die Sie verlinken, scheint zutreffen. –

+0

Nicht vertraut mit FindBugs oder was @SuppressWarnings Werte es unterstützt! OP sollte den engsten Wert verwenden, der seine Warnung beseitigt, um Ihr Anliegen oben anzugehen. – BadZen

0
InputStream is = ...; 
boolean report = ...; 
InputStreamReader isr = new InputStreamReader(is); 
BufferedReader br = new BufferedReader(isr); 
String line; 
while ((line = br.readLine()) != null) { 
    if (report) { 
     Debug.println(line); 
    } 
} 
+0

Ich hatte gesprungen, um zu vermeiden, 'Bericht' neu bewerten zu müssen bei jeder Iteration der Schleife. Vielleicht kümmert sich der Optimizer darum, aber ich würde es vorziehen, sich nicht auf eine bestimmte Optimierung zu verlassen. Ist es nicht das Ziel, viele Saiten zu konstruieren und zu zerstören, die ich nicht wirklich brauche? –