把混乱的日志等内容格式化后进行输出方便观看


package cn.cfm.demo.util;

import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName: ReaderFile
 * @Description: 格式化日志文件
 * @Author 
 * @Date 2020/11/12
 */
public class ReaderFile {

    /**
     * 单位缩进字符串。
     */
    private static String SPACE = "    ";

    private static String NUMBER = "###############################################################" +
            "####################################################################";

    public static void main(String[] args) {

        //输入文件路径 C:\Users\newtouch\Desktop\输入日志.txt
        String inputFileName ="C:\\Users\\chang\\Desktop\\输入日志.txt";
        //格式化后文件路径
        String outputFileName ="C:\\Users\\chang\\Desktop\\格式化日志.txt";

        //传入文件的两个路径
        fileJson(inputFileName,outputFileName);


    }


    public static void fileJson(String inputFileName,String outputFileName){

        int group =0;
        int index =0;

        String str1,str2,str3,str4,str5="";
        BufferedReader br = null;
        StringBuilder result = new StringBuilder();
        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream(inputFileName)));
            BufferedWriter writer = new BufferedWriter(new FileWriter(new File(outputFileName)));

            String str=new String();
            while((str = br.readLine())!=null){//使用readLine方法,一次读一行
                result.append(str);
            }
            br.close();

            //去除里面的\

            str1=result.toString().replace("\\\"","\"");
            str1 = str1.replaceAll("\\\\{1,}\"{1}","");
            str2=  str1.replace("\\n","").replace("\\t","");
            str3= str2.replace("<br/>","\r\n");
            str3= str3.replace("root","\r\nroot");
            //判断有几个分组
            group = way1(str3,"{\"ltype");


            for (int i = 1; i <=group ; i++) {
                if(i==group){
                    str4 =str3.substring( getFromIndex(str3,"\\{\"ltype",i));
                }else{
                    str4 =str3.substring( getFromIndex(str3,"\\{\"ltype",i), getFromIndex(str3,"\\{\"ltype",i+1));
                }

                if(str4.indexOf("<?xml")>0){
                    //调用处理xml的方法
                    str4=str4.replace("\\n","");
                    str4=str4.replace("\\t","");
               //     System.out.println("8888:"+str4.substring(str4.indexOf("<?xml"),str4.indexOf("\"}")));
                    str5 += str4.substring(0,str4.indexOf("<?xml"))+ format(str4.substring(str4.indexOf("<?xml"),str4.indexOf("\"}")))+"}";
              //      System.out.println("格式化后的xml::"+str5);
                }else{
                    str5 += str4;
                }


            }


            str5=str5.replace("{\"ltype\"","\r\n{\"ltype\"");
            str5=str5.replace("}\r\n{\"ltype\"","}\r\n"+NUMBER+"\r\n{\"ltype\"");

            //格式化json
            str5 = formatJson("一共是"+group+"组要格式化的数据:\r\n"+str5);

            writer.write(str5);
            writer.close();


        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    /**
     * @description: 子字符串modelStr在字符串str中第count次出现时的下标
     * @param str
     * @param modelStr
     * @param count
     * @return: int
     * @author: 
     * @date: 2020/11/12 16:19
     */
    public static  int getFromIndex(String str, String modelStr, Integer count) {

        //对子字符串进行匹配
        Matcher slashMatcher = Pattern.compile(modelStr).matcher(str);
        int index = 0;
        //matcher.find();尝试查找与该模式匹配的输入序列的下一个子序列
        while (slashMatcher.find()) {
            index++;
            //当modelStr字符第count次出现的位置
            if (index == count) {
                break;
            }
        }
        //matcher.start();返回以前匹配的初始索引。
        return slashMatcher.start();
    }

    /**
     * @description: 格式化xml
     * @param unformattedXml
     * @return: java.lang.String
     * @author: 
     * @date: 2020/11/12 16:13
     */

    public static  String format(String unformattedXml) {
        try {
            final Document document = parseXmlFile(unformattedXml);
            OutputFormat format = new OutputFormat(document);
            format.setLineWidth(65);
            format.setIndenting(true);
            format.setIndent(2);
            Writer out = new StringWriter();
            XMLSerializer serializer = new XMLSerializer(out, format);
            serializer.serialize(document);
            return out.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * @description:
     * @param in
     * @return: org.w3c.dom.Document
     * @author: 
     * @date: 2020/11/12 16:12
     */
    public static Document parseXmlFile(String in) {

        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputSource is = new InputSource(new StringReader(in));
            return db.parse(is);
        } catch (ParserConfigurationException e) {
            throw new RuntimeException(e);
        } catch (SAXException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @description: 返回格式化JSON字符串。
     * @param json 未格式化的JSON字符串。
     * @return: java.lang.String
     * @author: 
     * @date: 2020/11/12 16:14
     */
    public static String formatJson(String json) {

        StringBuffer result = new StringBuffer();

        int length = json.length();
        int number = 0;
        char key = 0;

        //遍历输入字符串。
        for (int i = 0; i < length; i++) {
            //1、获取当前字符。
            key = json.charAt(i);

            //2、如果当前字符是前方括号、前花括号做如下处理:
            //if((key == '[') || (key == '{') )
            if((key == '{') ) {
                //(1)如果前面还有字符,并且字符为“:”,打印:换行和缩进字符字符串。
                if((i - 1 > 0) && (json.charAt(i - 1) == ':'))
                {
                    result.append('\n');
                    result.append(indent(number));
                }

                //(2)打印:当前字符。
                result.append(key);

                //(3)前方括号、前花括号,的后面必须换行。打印:换行。
                result.append('\n');

                //(4)每出现一次前方括号、前花括号;缩进次数增加一次。打印:新行缩进。
                number++;
                result.append(indent(number));

                //(5)进行下一次循环。
                continue;
            }

            //3、如果当前字符是后方括号、后花括号做如下处理:
            //  if((key == ']') || (key == '}') ) {
            if( (key == '}') ) {
                //(1)后方括号、后花括号,的前面必须换行。打印:换行。
                result.append('\n');

                //(2)每出现一次后方括号、后花括号;缩进次数减少一次。打印:缩进。
                number--;
                result.append(indent(number));

                //(3)打印:当前字符。
                result.append(key);

                //(4)如果当前字符后面还有字符,并且字符不为“,”,打印:换行。
                if(((i + 1) < length) && (json.charAt(i + 1) != ','))
                {
                    result.append('\n');
                }

                //(5)继续下一次循环。
                continue;
            }

            //4、如果当前字符是逗号。逗号后面换行,并缩进,不改变缩进次数。
            if((key == ',')) {
                result.append(key);
                result.append('\n');
                result.append(indent(number));
                continue;
            }

            //5、打印:当前字符。
            result.append(key);
        }

        return result.toString();
    }


    /**
     * @description: 返回指定次数的缩进字符串。每一次缩进三个空格,即SPACE。
     * @param number 缩进次数。
     * @return: java.lang.String  指定缩进次数的字符串。
     * @author: 
     * @date: 2020/11/12 16:16
     */
    public static String indent(int number) {

        StringBuffer result = new StringBuffer();
        for(int i = 0; i < number; i++)
        {
            result.append(SPACE);
        }
        return result.toString();
    }


    /**
     * @description: 指定字符串在原字符串中出现的次数
     * @param st 原字符串
     * @param M  要找的内容
     * @return: int
     * @author: 
     * @date: 2020/11/12 16:15
     */
    public static int way1(String st,String M) {

        int count = 0;
        while(st.indexOf(M)>=0) {
            st=st.substring(st.indexOf(M)+M.length());
            count++;
        }
        System.out.println("指定字符串在原字符串中出现:"+count+"次");
        return count;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值