zoukankan      html  css  js  c++  java
  • 代码优化:对资源的close()建议分开操作和及时关闭流

    一、对资源的close()建议分开操作

    如下:

    try{
        XXX.close();
        YYY.close();
    }
    catch (Exception e){
        ...
    }

    建议改为

    try{
        XXX.close();
    }
    catch (Exception e){
        ...
    }
    try{
        YYY.close();
    }
    catch (Exception e){
        ...
    }

    正例:创建一张学生表

    public class Demo4DDL {
        public static void main(String[] args) {
            //1. 创建连接
            Connection conn = null;
            Statement statement = null;
            try {
                conn = DriverManager.getConnection("jdbc:mysql:///day24", "root", "root");
                //2. 通过连接对象得到语句对象
                statement = conn.createStatement();
                //3. 通过语句对象发送 SQL 语句给服务器
                //4. 执行 SQL
                statement.executeUpdate("create table student (id int PRIMARY key auto_increment, " +
                "name varchar(20) not null, gender boolean, birthday date)");
                //5. 返回影响行数(DDL 没有返回值)
                System.out.println("创建表成功");
            } catch (SQLException e) {
                e.printStackTrace();
            }
            //6. 释放资源
            finally {
                //关闭之前要先判断
                if (statement != null) {
                    try {
                        statement.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if (conn != null) {
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    正例2:访问数据库的工具类

    public class JdbcUtils {
        //可以把几个字符串定义成常量:用户名,密码,URL,驱动类
        private static final String USER = "root";
        private static final String PWD = "root";
        private static final String URL = "jdbc:mysql://localhost:3306/day24";
        private static final String DRIVER= "com.mysql.jdbc.Driver";
        /**
        * 注册驱动
        */
        static {
            try {
                Class.forName(DRIVER);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        /**
        * 得到数据库的连接
        */
        public static Connection getConnection() throws SQLException {
            return DriverManager.getConnection(URL,USER,PWD);
        }
        /**
        * 关闭所有打开的资源
        */
        public static void close(Connection conn, Statement stmt) {
            if (stmt!=null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn!=null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        /**
        * 关闭所有打开的资源
        */
        public static void close(Connection conn, Statement stmt, ResultSet rs) {
            if (rs!=null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            close(conn, stmt);
        }
    }

    反例:

    public String downloadAttachment(Integer type, String downLoadPath, HttpServletRequest request, HttpServletResponse response) {
            //这里获取的下载链接 http://sk.sit.fosuntech.cn/group1/M00/00/72/CqYKHVn69wyAMl6YAAVf953sp4Y075.pdf
            BufferedInputStream bis = null;
            BufferedOutputStream bos = null;
            try {
                //响应二进制流
                response.setContentType("application/octet-stream");
                response.reset();//清除response中的缓存
                //根据网络文件地址创建URL
                URL url = new URL(downLoadPath);
                //获取此路径的连接
                URLConnection conn = url.openConnection();
                Long fileLength = conn.getContentLengthLong();//获取文件大小
                //设置reponse响应头,真实文件名重命名,就是在这里设置,设置编码
                if (type.equals(1)) {
                    response.setHeader("Content-Disposition",
                            "attachment; filename=" + fileName);
                }
    
                response.setHeader("Content-Length", String.valueOf(fileLength));
    
                bis = new BufferedInputStream(conn.getInputStream());//构造读取流
                bos = new BufferedOutputStream(response.getOutputStream());//构造输出流
                byte[] buff = new byte[1024];
                int bytesRead;
                //每次读取缓存大小的流,写到输出流
                while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                    bos.write(buff, 0, bytesRead);
                }
                response.flushBuffer();//将所有的读取的流返回给客户端
            } catch (IOException e) {
                logger.error("文件下载失败!", e);
            } finally {
                try {
                    if (null != bis) {
                        bis.close();
                    }
                    if (null != bos) {
                        bos.close();
                    }
                } catch (IOException e) {
                    logger.error("文件下载失败!", e);
                }
            }
            return null;
        }

    反例2:

    public static String readFile( ){
            String str1 ="";
            FileReader fr ;
            InputStreamReader isr = null;
            BufferedReader br = null;
            FileInputStream fileInputStream =null;
            
            try{
                fileInputStream = new FileInputStream(new File("C:/Users/Scot/Desktop/application-cr999Test.properties"));
                String str = "";
                isr  = new InputStreamReader(fileInputStream);
                br = new BufferedReader(isr);
                while((str = br.readLine()) != null){
                    if(isEncryptItem(str)){
                        int index = str.indexOf("=");
                        String encryptTitle =str.substring(0,index+1);
                        String encryptWord = str.substring(index+1,str.length());
                        String encryptedWord =(String) getEncryptedParams(encryptWord).get("input");
                        str = encryptTitle+encryptedWord_prefix+encryptedWord+encryptedWord_suffix;
                    }
                    str1+=str+"\n";
                }
    
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                try {
                    br.close();
                    isr.close();
                    fileInputStream.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            return str1;
        }

    二、及时关闭流

    Java编程过程中,进行数据库连接、I/O流操作时务必小心,在使用完毕后,及时关闭以释放资源。因为对这些大对象的操作会造成系统大的开销,稍有不慎,将会导致严重的后果。

  • 相关阅读:
    通过通过url routing解决UIViewController跳转依赖
    vs2010下配置CUDA出现kernel launch failed问题,内核无效
    ganglia监控自己定义metric实践
    faq
    Android进阶图片处理之三级缓存方案
    操作系统 内存管理(一)
    rocketmq消费队列代码
    网页固定側栏的做法
    web爬虫之登录google paly 商店
    C之内存地址
  • 原文地址:https://www.cnblogs.com/zwh0910/p/15808944.html
Copyright © 2011-2022 走看看