java 如何忽略InputStream中的所有数据而不影响静态分析工具?

sbdsn5lh  于 12个月前  发布在  Java
关注(0)|答案(4)|浏览(108)

我有一个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_NULL_READLINE)我正在调用readLine,并且 * 仅 * 检查它是否为null,不对结果做任何事情。它的分析是正确的,但我不想是否有一些习惯的方法来消费和忽略流中的所有数据,这样它就不会看起来像是对FindBugs来说是个错误吗

v09wglhw

v09wglhw1#

通过在InputStream上使用skip,您可以避免构造被丢弃的String对象。(InputStreamReaderBufferedReader也有skip方法,但是如果你想跳过整个流,你并不需要InputStreamReader的字符解码功能,也不需要BufferedReader的行检测和缓冲区管理功能。

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

字符串
循环不太可能运行多次--您需要首先从流中读取8 EB--但循环是为了消除另一个FindBugs警告(SR_NO_BURKED),如果您在没有检查返回值的情况下调用skip,则会发生这种情况。
使用SuppressWarnings annotation使编译器静默是无效的,因为不是 compiler 担心未使用的返回值。annotation没有存储在编译后的代码中,所以字节码分析器(如FindBugs)无论如何都看不到它。此外,SuppressWarnings抑制的警告在这种情况下都不适用;特别是,unused不适用,因为 * 返回值 * 不在编译器检查的内容之列。
但是,您可以尝试使用生成警告的静态分析工具提供的其他抑制机制,而不是Java内置的SuppressWarnings

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添加到您的构建依赖项中,但不会添加到程序的 * 运行时 * 依赖项中。

bxfogqkk

bxfogqkk2#

尝试使用@ SuppressNotation。
检查此链接Excluding warnings using @SuppressWarnings
关于它的一些笔记:

  • “如果没有annotation,编译器会抱怨本地变量s从未被使用。有了annotation,编译器会默默地忽略foo方法本地的警告。这使得可以将警告保留在同一编译单元或同一项目的其他位置。"*
xytpbqjk

xytpbqjk3#

老问题,但我遇到了同样的问题。我使用ProcessBuilder运行“其他”进程的标准输出,我想附加。
如果我们使用ProcessBuilder来管理其他进程,那么从Java 9开始,我们可以重定向输出。
processBuilder.redirectOutput(ProcessBuilder.Redirect.DISCARD)
从文件;
指示子进程输出将被丢弃。典型的实现通过写入操作系统特定的“空文件”来丢弃输出

public static final Redirect DISCARD = new Redirect() {
   ...
}

字符串

jvidinwx

jvidinwx4#

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

字符串

相关问题