如何在不跳过静态分析工具的情况下忽略InputStream中的所有数据?

时间:2016-05-03 17:32:05

标签: java inputstream findbugs

我有一个InputStream附加到另一个进程的stdout。我有时需要从流中记录数据,有时则不需要。即使我不关心输出,我仍然需要读取它,以便其他进程不会因为完整的输出缓冲而阻塞。我使用以下代码有选择地记录输出:

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检查它是否为空,没有对结果做任何事情。它的分析是正确的,但我不希望在这种情况下对结果做任何事情。是否有一些惯用的方式来消耗和忽略流中的所有数据,这样看起来可能看起来不像FindBugs?

3 个答案:

答案 0 :(得分:1)

尝试使用@SuppressWarnings表示法。

点击此链接PHP's list

关于它的一些注意事项:

"如果没有注释,编译器会抱怨从不使用局部变量s。使用注释,编译器在本地静默忽略此警告到foo方法。这样可以将警告保留在同一编译单元或同一项目的其他位置。"

答案 1 :(得分:1)

您可以使用String上的skip来避免构建被抛弃的InputStream个对象。 (InputStreamReaderBufferedReader也有skip种方法,但如果您想跳过整个流,则不需要进行字符解码InputStreamReader的功能或BufferedReader的行检测和缓冲管理功能。)

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

循环不太可能运行多次 - 你需要首先从流中读取8艾字节 - 但是如果你调用skip,循环就可以平息另一个FindBugs警告(SR_NO_CHECKED)没有检查返回值。

使用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添加到构建依赖项中。但是,它没有添加到程序的运行时依赖项中。

答案 2 :(得分: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);
    }
}