簡體   English   中英

如何在不跳過靜態分析工具的情況下忽略InputStream中的所有數據?

[英]How do I ignore all data from an InputStream without tripping up static-analysis tools?

我有一個附加到另一個進程的stdout的InputStream 我有時需要從流中記錄數據,有時則不需要。 即使我不關心輸出,我仍然需要讀取它,以便其他進程不會因為完整的輸出緩沖而阻塞。 我使用以下代碼有選擇地記錄輸出:

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

但是,在第二個while循環中,FindBugs警告(RV_DONT_JUST_NULL_CHECK_READLINE)我正在調用readLine並且檢查它是否為null,而不是對結果做任何事情。 它的分析是正確的,但在這種情況下我不想對結果做任何事情。 是否有一些慣用的方式來消費和忽略流中的所有數據,這樣看起來可能看起來不像FindBugs的錯誤?

嘗試使用@SuppressWarnings表示法。

檢查此鏈接使用@SuppressWarnings排除警告

一些關於它的說明:

“如果沒有注釋,編譯器會抱怨從不使用局部變量。使用注釋,編譯器在本地靜默忽略此警告到foo方法。這樣可以將警告保留在同一編譯單元的其他位置或同一個項目。“

您可以通過在InputStream上使用skip來避免構造剛剛被拋棄的String對象。 InputStreamReaderBufferedReader也有skip的方法,但如果你希望跳過整個流,你並不真正需要的字符解碼功能InputStreamReader或線路檢測功能,並且緩存管理功能BufferedReader 。)

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

循環不太可能運行多次 - 你需要首先從流中讀取8艾字節 - 但循環是為了平息另一個FindBugs警告(SR_NO_CHECKED),如果你在不檢查返回值的情況下調用skip ,就會發生這種情況。


使用SuppressWarnings注釋使編譯器靜音是無效的,因為編譯器並不擔心未使用的返回值。 注釋不存儲在已編譯的代碼中,因此像FindBugs這樣的字節碼分析器無論如何都看不到它。 此外, SuppressWarnings抑制的警告都不適用於這種情況; 特別是, unused不適用,因為返回值不屬於編譯器檢查的內容。

但是,您可以嘗試使用由生成警告的靜態分析工具提供的其他一些抑制機制,而不是Java內置的SuppressWarnings 在FindBugs的情況下,這是SuppressFBWarnings注釋。

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

要最小化警告抑制的范圍,可以使用自己的方法隔離警告生成代碼。 例如:

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

然后,您可以在給定的上下文中使用該方法:

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

需要注意的是,這會將FindBugs注釋jar添加到構建依賴項中。 但是,它沒有添加到程序的運行時依賴項中。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM