zoukankan      html  css  js  c++  java
  • java 读写yml文件,修改文件内容保持原格式

    我理解的yml文件

    在我们学习过springboot项目的同学对这个文件肯定是特别熟悉,通常我们都是用它来修改保存我们的项目配置,最简单的就是数据库的配置,然后就是资源读取配置,redies配置,缓存配置,以及jwt的配置等等,因为yml文件主要用于我们的项目配置,所以一个特点就是易于人们阅读,修改;即使一个刚接触yml文件的人加上简单的注释,肯定也能够看懂打部分内容的;
    我总结的特点就是:

    1. 直观,易于阅读,修改
    2. 可以把对象的层次结构展现得很直观
    3. 用key:value的方式属性
    4. 用空格数量表示层级关系

    我工作中遇到的问题

    大家估计在spring中主要都是读取yml文件,所以对于写yml文件的过程经历不太多,我的项目系统是自己的java框架,然后要集成另外的一个spring项目,当我的项目修改数据库信息的时候同时也要修改这个springboot项目的数据库配置信息,那么就存在一个对yml的读和写的过程,我经过百度后加上自己的代码,就得到了自己想要的效果;主要用到了ymal这个开源工具类;
    maven依赖

            <dependency>
                <groupId>org.yaml</groupId>
                <artifactId>snakeyaml</artifactId>
                <version>1.25</version>
            </dependency>
    
    

    读取

    关键代码,ymal工具自动将yml文件转换为map结构的对象

    //解析yml文件的关键类
            Yaml yml =null;
            try (FileInputStream in = new FileInputStream(file)){
    
                yml = new Yaml();
                obj = (Map)yml.load(in);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            Map<String,Object> springMap =(Map)obj.get("spring");
    

    写入

    关键代码,

    try (FileWriter writer = new FileWriter(file)) {
                //writer.write(yml.dump(obj));
                writer.write(yml.dumpAsMap(obj));
               //writer.write(yml.dumpAs(obj, Tag.MAP, DumperOptions.FlowStyle.BLOCK));
               //可以自定义写入格式
                //writer.write(yml.dumpAs(obj, Tag.MAP, DumperOptions.FlowStyle.FLOW));
            } catch (IOException e) {
                e.printStackTrace();
            }
    

    我用的是dumpAsMap方法,这个方法能够自动把map结构的对象转为yml文件的key:value的结构,map层级用两个空格表示,但是我的这个项目用了4个空格,所以后面我还得重新特殊处理一下;

    完整代码,

    因为我的主要目的是修改数据库配置信息,由于项目系统支持了很多类型的数据库,所以我要适配各种数据库;

    @SpringBootTest
    public class DemoTest {
        @Test
        public void readYmlTest()  {
    
            //要读的文件路径
            String filePath ="C:"+File.separator+"Users"+File.separator+"17247"+File.separator+"Desktop"+File.separator+"application-exclusive.yml";
            Map<String,Object> obj =null;
            File file = new File(filePath);
    
            //解析yml文件的关键类
            Yaml yml =null;
            try (FileInputStream in = new FileInputStream(file)){
    
                yml = new Yaml();
                obj = (Map)yml.load(in);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            Map<String,Object> springMap =(Map)obj.get("spring");
    
    
            String url = "jdbc:oracle:thin:@127.0.0.1:1521/orcl";
            //String url = "jdbc:dm://127.0.0.1:5236/DMSERVER?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8";
            String usesrname = "poc";
            String pwd = "ENC(w2PXuzg+U60Zs2MA/FouyQ==)";
    
            AEDatasourceFactory AeDatasourceFactory = new AEDatasourceFactory(url,usesrname,pwd);
            //根据不同数据库更新模板
            AeDatasourceFactory.updateDatasourceTemplet(springMap);
            try (FileWriter writer = new FileWriter(file)) {
                //writer.write(yml.dump(obj));
                //writer.write(yml.dumpAsMap(obj));
               writer.write(yml.dumpAs(obj, Tag.MAP, DumperOptions.FlowStyle.BLOCK));
                //writer.write(yml.dumpAs(obj, Tag.MAP, DumperOptions.FlowStyle.BLOCK));
            } catch (IOException e) {
                e.printStackTrace();
            }
            //重新读取文件调整空格
            StringBuffer buffer = new StringBuffer();
            String newLine =System.lineSeparator();
            try (BufferedReader input = new BufferedReader(
                    new InputStreamReader(new FileInputStream(file), "utf-8"));) {
                String line;
                while ((line = input.readLine()) != null) {
                    String lineTrim = line.trim();
                    String pre ="";
                    if(line.startsWith("  ")){
                        int length = line.length()-lineTrim.length();
                        pre = this.getSpaceByNum(length*2);
                    }
                    if(lineTrim.startsWith("- ")){
                        //有横杠的需要再加4个空格
                        pre = pre+this.getSpaceByNum(4);
                    }
                    buffer.append(pre+lineTrim);
                    buffer.append(newLine);
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try (BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(new FileOutputStream(filePath, false), "utf-8"))) {
    
                writer.write(buffer.toString());
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
        //获取指定数量的空格
        private String getSpaceByNum(int num){
            StringBuffer buffer = new StringBuffer();
            for(int i=0;i<num;i++){
                buffer.append(" ");
            }
            return buffer.toString();
        }
    
        
        private String getAEEncryptPassword(String input) {
    
            return input ;
        }
    }
    
    

    适配数据库工厂类

    import java.util.LinkedHashMap;
    import java.util.Map;
    
    /**
     * AE数据源模板工厂类
     */
    public class AEDatasourceFactory {
        //oracle数据库
        private final String ORACLE_TYPE="jdbc:oracle";
        //sqlserver数据库类型
        private final String SQLSERVER_TYPE="jdbc:oracle";
        //db2数据库
        private final String DB2_TYPE="jdbc:db2";
        //达梦数据库
        private final String DM_TYPE="jdbc:dm";
        //pg数据库
        private final String PG_TYPE="dbc:postgresql";
        //高斯数据库
        private final String GAUSS_TYPE="jdbc:zenith";
    
        String url;
        String username;
        String password;
        public AEDatasourceFactory(String url, String username, String password) {
    
            this.url=url;
            this.username=username;
            this.password=password;
    
        }
    
        /**
         * 获取更新数据源模板
         * @param springMap
         */
        public void updateDatasourceTemplet(Map<String,Object> springMap){
            Map<String,Object> dataSource = (Map<String,Object>)springMap.get("datasource");
            Map<String,Object> jpaMap = (Map<String,Object>)dataSource.get("jpa");
            if(jpaMap==null){
                //应该是jpa和datasource同级的,
                // 但是他们提供的可能是不同级的
                jpaMap = springMap.get("jpa")!=null?(Map<String,Object>)springMap.get("jpa"):new LinkedHashMap<>();
            }
            dataSource.clear();
            Map<String,Object> hikari = new LinkedHashMap<>();
            hikari.put("auto-commit",false);
            if(url.startsWith(ORACLE_TYPE) || url.startsWith(SQLSERVER_TYPE)){
                dataSource.put("type","com.zaxxer.hikari.HikariDataSource");
                dataSource.put("url",url);
                dataSource.put("username",username);
                dataSource.put("password",getAEEncryptPassword(password));
                dataSource.put("hikari",hikari);
    
            }else if(url.startsWith(DM_TYPE)){
                dataSource.put("url",url);
                dataSource.put("username",username);
                dataSource.put("password",getAEEncryptPassword(password));
                dataSource.put("driver-class-name","dm.jdbc.driver.DmDriver");
            }else if(url.startsWith(DB2_TYPE)){
                dataSource.put("type","com.zaxxer.hikari.HikariDataSource");
                dataSource.put("driver-class-name","com.ibm.db2.jcc.DB2Driver");
                dataSource.put("hikari",hikari);
            }else if(url.startsWith(GAUSS_TYPE)){
                dataSource.put("url",url);
                dataSource.put("username",username);
                dataSource.put("password",getAEEncryptPassword(password));
                dataSource.put("driver-class-name","com.huawei.gauss.jdbc.ZenithDriver");
            }else if(url.startsWith(PG_TYPE)){
                dataSource.put("type","com.zaxxer.hikari.HikariDataSource");
                dataSource.put("url",url);
                dataSource.put("username",username);
                dataSource.put("password",getAEEncryptPassword(password));
                dataSource.put("hikari",hikari);
                //pg没有jpa
                jpaMap=null;
            }
            if(jpaMap!=null){
                getJpaTemplet(jpaMap);
                springMap.put("jpa",jpaMap);
            }
        }
        private void getJpaTemplet(Map<String,Object> jpaMap){
            if(jpaMap==null){
                return;
            }
            jpaMap.clear();
            Map<String,Object> properties = new LinkedHashMap<>();
            if(url.startsWith(ORACLE_TYPE) || url.startsWith(SQLSERVER_TYPE)){
    
                jpaMap.put("database-platform","org.hibernate.dialect.Oracle12cDialect");
                jpaMap.put("database","ORACLE");
                jpaMap.put("show-sql",false);
                properties.put("hibernate.id.new_generator_mappings",true);
                properties.put("hibernate.connection.provider_disables_autocommit",true);
                properties.put("hibernate.cache.use_second_level_cache",false);
                properties.put("hibernate.cache.use_query_cache",false);
                properties.put("hibernate.generate_statistics",false);
                jpaMap.put("properties",properties);
            }else if(url.startsWith(GAUSS_TYPE)){
                //不知道为啥要用oracle的
                properties.put("hibernate.dialect","org.hibernate.dialect.Oracle12cDialect");
                jpaMap.put("properties",properties);
            }else if(url.startsWith(DM_TYPE)){
                properties.put("hibernate.dialect","org.hibernate.dialect.DmDialect");
                jpaMap.put("properties",properties);
            }else if(url.startsWith(PG_TYPE)){
    
            }else if(url.startsWith(DB2_TYPE)){
                properties.put("hibernate.dialect","com.diwork.intelliv.workbench.auth.dialect.CustomDB2Dialect");
                properties.put("hibernate.auto_quote_keyword",true);
                jpaMap.put("properties",properties);
                jpaMap.put("show-sql",true);
                Map<String,Object> hibernate = new LinkedHashMap<>();
                Map<String,Object> naming = new LinkedHashMap<>();
                naming.put("physical-strategy","org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl");
                hibernate.put("naming",naming);
                jpaMap.put("hibernate",hibernate);
            }
        }
        //密码加密方法
        private String getAEEncryptPassword(String input) {
    
            return input ;
        }
    }
    
    

    这样修改了指定的内容,而且还保证了文件的原格式,但有个问题是文件的注释会丢失;

  • 相关阅读:
    vim 多个文件切换
    Ruby 格式化代码 vim
    Ruby 配置vimrc
    print puts p
    开机跳过开机选择系统的选项界面
    Linux学习笔记:rm删除文件和文件夹
    Linux学习笔记:ps -ef、ps aux、kill -9
    Linux学习笔记:ctrl+z、ctrl+c、ctrl+d的区别
    Shell学习笔记:<<EOF子命令
    Linux学习笔记:crontab定时任务
  • 原文地址:https://www.cnblogs.com/liu-ya/p/13556501.html
Copyright © 2011-2022 走看看