【问题标题】:Unreleased Resource: Streams未发布的资源:流
【发布时间】:2025-12-20 19:10:04
【问题描述】:

嗨朋友们,我在 fortify 报告中收到以下代码的警告:

 if (null != serverSocket) {

     OutputStream socketOutPutStream = serverSocket
       .getOutputStream();
     if (null != socketOutPutStream) {

      oos = new ObjectOutputStream(socketOutPutStream);
      if (null != oos) {
       int c;
       log.info("i am in Step 3 ooss " + oos);
       while ((c = mergedIS.read()) != -1) {
        oos.writeByte(c);
       }
      }
      log.info("i am in Step 4 ");

     }

    }

在我提到的 catch 块中:

catch (UnknownHostException e) {
    //catch exception Vibhas added 
    log.info("UnknownHostException occured");

   } catch (IOException e) {
    //catch exception Vibhas added
    log.info("IOException occured");

   } catch (Exception e) {
    //catch exception
    //log.info("error occured in copyFile in utils-->"+e.getMessage()+"file name is-->"+destiFileName);
   }finally{

    if (null != oos){

     oos.flush();
     oos.close();

      }
      catch (Exception e) {
     //catch exception
      }

    }

我在强化报告中得到的警告是:

Abstract: The function copyFile() in ODCUtil.java sometimes fails to release a system resource
allocated by getOutputStream() on line 61.
Sink: ODCUtil.java:64 oos = new ObjectOutputStream(socketOutPutStream)()
62 if (null != socketOutPutStream) {
63
64 oos = new ObjectOutputStream(socketOutPutStream);
65 if (null != oos) {
66 int c;

完整代码:

public boolean copyFile(InputStream is, String destiFileName) {
    boolean flag = false;
    {
        InputStream mergedIS = null;
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        ByteArrayInputStream str = null;
        try {

            //Step 1 : first get the input stream of file content and file name
            // then merge into one input stream
            log.info("i am in Step 1 ");
            log.info("destiFileName got-->" + destiFileName);
            log.info("is  got in coptFile function -->" + is);
            destiFileName = "@" + destiFileName + "@";
            log.info("destiFileName sending to server-->" + destiFileName);
            str = new ByteArrayInputStream(destiFileName.getBytes());
            log.info("The ByteArrayInputStream we got is  "
                    + str.toString());
            mergedIS = new SequenceInputStream(str, is);

            //Step 2 : Make a connection to server ie DB server
            log.info("i am in Step 2 ");
            String serverIP = "172.17.119.67";
            int serverPort = 1522;
            Socket serverSocket = new Socket(serverIP, serverPort);

            //Step 3 : We have to write the merged inputstream to outputstream of server, ie socket of server
            log.info("i am in Step 3 ");

            //added by vibhas to resolve Unreleased resource

            if (null != serverSocket) {

                OutputStream socketOutPutStream = serverSocket
                        .getOutputStream();
                if (null != socketOutPutStream) {

                    oos = new ObjectOutputStream(socketOutPutStream);
                    if (null != oos) {
                        int c;
                        log.info("i am in Step 3 ooss " + oos);
                        while ((c = mergedIS.read()) != -1) {
                            oos.writeByte(c);
                            socketOutPutStream.close();
                        }
                    }
                    log.info("i am in Step 4 ");

                }

            }

            //Step 4 : We have to get an acknowledgment from server that , server has copied the file properly
            //this is the same .

            if (true) {
                log.info("i am in Step 4 11");
                flag = true;
            }
        } catch (UnknownHostException e) {
            //catch exception Vibhas added 
            log.info("UnknownHostException occured");

        } catch (IOException e) {
            //catch exception Vibhas added
            log.info("IOException occured");

        } catch (Exception e) {
            //catch exception
            //log.info("error occured in copyFile in utils-->"+e.getMessage()+"file name is-->"+destiFileName);
        } finally {
            try {
                if (null != str) {
                    str.close();
                }
                if (null != ois) {
                    ois.close();
                }
                if (null != mergedIS) {
                    mergedIS.close();
                }
                if (null != oos) {
                    oos.flush();
                    oos.close();
                }
            } catch (Exception e) {
                //catch exception
            }
        }
    }
    log.info("finally returned flag-->" + flag);
    return flag;
}

【问题讨论】:

  • 请粘贴整个代码片段,正确缩进。或者上面的代码没有编译(oos.close 的catch 没有匹配的try 块)或者缩进太混乱了。
  • 有什么解决方案吗?

标签: java


【解决方案1】:

好吧,你关心可能为时已晚,但我有个主意。在finally 块中,在调用close() 之前调用flush()。但是flush()can throw an IOException

【讨论】:

    【解决方案2】:

    不是一个很好的 try/catch 结构。一方面,问问自己: 如果str.close();(在finally 块的开头)抛出异常会发生什么?

    最好看这里:Java io ugly try-finally block

    顺便说一句:这很难看; new 永远不会返回 null

      oos = new ObjectOutputStream(socketOutPutStream);
      if (null != oos) {
    

    BTW2:您确定需要ObjectOutputStream 吗?很多人用它来写纯字节,但这不是想法(它是用于序列化对象),原始的 OutputStream 就足够了。

    【讨论】:

      【解决方案3】:

      我不知道什么是强化报告,但你在哪里关闭socketOutPutStream?它会因为关闭oos 而被关闭吗?即便如此,socketOutPutStream 也有可能不是null 并且需要关闭但oos 为空。

      【讨论】:

      • Hi Hemal Fortify Report 用于检查代码漏洞对任何类型的攻击(专门用于安全测试)。我已经关闭了 socketOutPutStream 但仍然遇到同样的问题。我在这里放了完整的代码,以便您提出建议。
      • 如何最终阻止异常,所有异常都在控件进入最终阻止之前处理。我也在 str.close 语句之前检查空条件。请澄清。还请解释为什么在我之前的代码中提到了 Unreleased 资源的情况。我同意 new 运算符不会返回 null。感谢您的建议。
      • 在 try 块中,您在几个对象上调用 cloase。如果其中任何一个引发异常,则不会为其余对象调用 close。尝试将每个关闭包装在单独的 try{ ...close(); } 捕捉 {..}