我有一个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?
答案 0 :(得分:1)
尝试使用@SuppressWarnings表示法。
点击此链接PHP's list
关于它的一些注意事项:
"如果没有注释,编译器会抱怨从不使用局部变量s。使用注释,编译器在本地静默忽略此警告到foo方法。这样可以将警告保留在同一编译单元或同一项目的其他位置。"
答案 1 :(得分:1)
您可以使用String
上的skip
来避免构建被抛弃的InputStream
个对象。 (InputStreamReader
和BufferedReader
也有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);
}
}