美文网首页
Java读取File并且筛选部分内容一行一行追加写入

Java读取File并且筛选部分内容一行一行追加写入

作者: 莫问以 | 来源:发表于2019-06-20 14:36 被阅读0次

    之前生产变更产生的后遗症,就是需要去读取日志并且筛选出其中的xml报文,写入另一个txt中,然后读取报文中部分字段的值,组装为sql的修改语句,我们简单看下,比方说原日志文件如下:

    2019-04-17 你好,我正在模拟日志
    业务凭证原文:<?xml version="1.0" encoding="GBK"?>
    <Voucher>
      <Id>1240569</Id>
      <AdmDivCode>532525</AdmDivCode>
      <StYear>2019</StYear>
      <VtCode>8202</VtCode>
      <VouDate>20190513</VouDate>
      <VoucherNo>2550011010441</VoucherNo>
      <DetailList>
        <Detail>
          <Id>1240568</Id>
          <VoucherDetailNo>2550011000002</VoucherDetailNo>
        </Detail>
      </DetailList>
    </Voucher>
    君不见,黄河之水天上来,奔流到海不复回。 
    君不见,高堂明镜悲白发,朝如青丝暮成雪。 
    业务凭证原文:<?xml version="1.0" encoding="GBK"?>
    <Voucher>
      <Id>1240570</Id>
      <AdmDivCode>532525</AdmDivCode>
      <StYear>2019</StYear>
      <VtCode>8202</VtCode>
      <VouDate>20190513</VouDate>
      <VoucherNo>2550011010442</VoucherNo>
      <DetailList>
        <Detail>
          <Id>1240571</Id>
          <VoucherDetailNo>2550011000003</VoucherDetailNo>
        </Detail>
      </DetailList>
    </Voucher>
    人生得意须尽欢,莫使金樽空对月。 
    天生我材必有用,千金散尽还复来。 
    啊哈哈哈哈哈哈哈哈哈哈
    

    我们需要取出业务凭证原文:的内容存入txt,先看代码:

    package com.kai;
    
    import java.io.*;
    
    public class TestIO {
    
        // 写开关--结束
        public static boolean writeBreak(String str) {
            boolean result = true;
            if (str.contains("</Voucher>")) {
                result = false;
            }
            return result;
        }
    
        public static void readTxtFile() throws IOException {
            String path = "C:\\Users\\admin\\Desktop\\0620\\yuan.txt"; // 原日志文件
    
            String filename = "C:\\Users\\admin\\Desktop\\0620\\xml.txt"; // 存xml文件
    
            File file = new File(path);// 文件路径
    
            FileReader fileReader;
    
            boolean writeFolad = false;
            boolean writeEnd = false;
            try {
                fileReader = new FileReader(file);
                LineNumberReader reader = new LineNumberReader(fileReader);
    
                String txt = "";
                while (txt != null) {
    
                    txt = reader.readLine();
                    System.err.println(txt);
                    if (txt != null && txt.trim().length() > 0) {
                        if (txt.contains("<?xml version=\"1.0\" encoding=\"GBK\"?>")) {
                            writeFolad = true;
                            writeEnd = true;
                        }
    
                        if (writeFolad && writeEnd && writeBreak(txt)) {
    
                            if (txt != null && txt.trim().length() > 0) {
                                System.out.println("开始写==========");
                                appendMethod(filename, txt);
                            }
    
                        } else if (writeEnd && !writeBreak(txt)) {
                            appendMethod(filename, txt); // 追加结束写入
                            appendMethod(filename, "\t\n"); // 空一格
                            writeEnd = false; // 标志一段xml正式写完
                        } else {
                            writeFolad = false;
                        }
    
                    } else {  // 如果一行为空 继续
                        continue;
                    }
    
                }
                System.out.println("读取完毕!!!");
                reader.close();
                fileReader.close();
            } catch (FileNotFoundException e) {
    
                e.printStackTrace();
            }
        }
    
        public static void main(String args[]) {
    
            try {
                readTxtFile();
            } catch (IOException e) {
                System.err.println("读取出错啦。。。。。");
                e.printStackTrace();
            }
            System.err.println("执行成功");
        }
    
        // 追加写入 
        public static void appendMethod(String fileName, String content) {
            try {
                // 打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件
                FileWriter writer = new FileWriter(fileName, true);
                writer.write(content + "\n");
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        // 读取xml文件 输出SQL语句
    
    }
    

    打开xml.txt文件,报文已经写入,但是“业务凭证原文:”这几个我们可以采用批量替换,也可以程序中写入时候replace一下。然后接下来,就需要读取xml报文中明细单<Detail>中的<Id>和<VoucherDetailNo>的值,拼装为sql语句输出,就比如说up.sql文件格式是可执行sql脚本,代码如下:

    // 读取xml文件 输出SQL语句
        public static void readXmlToSql() throws IOException {
            String path = "C:\\Users\\admin\\Desktop\\0620\\xml.txt"; // 原xml文件
    
            String filename = "C:\\Users\\admin\\Desktop\\0620\\up.sql"; // sql语句文件
    
            String sqlStr = "UPDATE T_ECFN_PAY_LIST SET VOUCHER_DETAIL_NO='";
            String sqlStart = "' WHERE ID='";
            String sql = null;
            String sqlEnd = "';"; // 表示结束
            String ID = "";
            String detailNo = "";
    
            File file = new File(path);// 文件路径
    
            FileReader fileReader;
    
            boolean startXml = false; // 明细单标志开关 意味找到明细
            boolean idXml = false; // 明细单Id开关 意味需要写入
            boolean voucherXml = false; // 明细单VoucherDetailNo开关 意味需要写入
            boolean toto = false; // 开关控制器 写完sql归置
            boolean totoVoucher = false; // 开关控制器 写完sql归置 两个开关控制一个流程
            try {
                fileReader = new FileReader(file);
                LineNumberReader reader = new LineNumberReader(fileReader);
    
                String txt = "";
                while (txt != null) {
    
                    txt = reader.readLine();
    
                    if (txt != null && txt.trim().length() > 0) {
                        // 明细单标志
                        if (txt.contains("<Detail>")) {
                            startXml = true;
                        }
    
                        if (startXml && writeXmlEnd(txt)) {
    
                            if (txt != null && txt.trim().length() > 0) {
                                if (txt.contains("<Id>")) {
                                    ID = SqlTo(txt);
                                    idXml = true; // 表示Id已经取到值
                                    toto = true; // 确认id可以写入
                                }
                                if (txt.contains("<VoucherDetailNo>")) {
                                    detailNo = SqlTo(txt);
                                    voucherXml = true; // 表示VoucherDetail已经取到值
                                    totoVoucher = true; // 表示确认可以写入
                                }
                                if (idXml && voucherXml && toto && totoVoucher) {
                                    sql = sqlStr + detailNo + sqlStart + ID + sqlEnd;
                                    System.err.println("sql===" + sql);
                                    appendMethod(filename, sql);
                                    // 写完后归置初始态 表示一条语句写入成功
                                    toto = false; // 归置
                                    totoVoucher = false; // 归置
                                }
                            }
    
                        } else {
                            startXml = false;
                        }
    
                    } else { // 如果一行为空 继续
                        continue;
                    }
    
                }
                System.out.println("sql写入完毕!!!");
                reader.close();
                fileReader.close();
            } catch (FileNotFoundException e) {
    
                e.printStackTrace();
            }
        }
    
        // 写开关--结束
        public static boolean writeXmlEnd(String str) {
            boolean result = true;
            if (str.contains("</Detail>")) {
                result = false;
            }
            return result;
        }
    
        public static String SqlTo(String txt) {
            String str = null;
            if (txt != null && txt.trim().length() > 0) {
                if (txt.contains("<Id>")) {
                    str = txt.replace("<Id>", "").replace("</Id>", "").trim().toString();
                }
                if (txt.contains("<VoucherDetailNo>")) {
                    str = txt.replace("<VoucherDetailNo>", "").replace("</VoucherDetailNo>", "").trim().toString();
                }
    
            }
            return str;
        }
    
    可执行脚本文件.png

    最后,main方法调用readXmlToSql()即大功告成!!!为什么要单独筛选出xml写入到txt文件中呢?因为xml报文的交易标识符有很多,我只是提取了8202交易标识符的xml报文的明细值,实际比这个复杂得多,我们需要单独提取出某一类交易标识符的xml报文,然后再取相应的值,就相对比较简单,这只是个思路!

    这种解决思路Bug比较大,如果要取N个字段的值,那么如何控制sql语句不重复,就成了一个很大的问题!所以如果各位有更好办法的,欢迎提供!!

    相关文章

      网友评论

          本文标题:Java读取File并且筛选部分内容一行一行追加写入

          本文链接:https://www.haomeiwen.com/subject/edpqxctx.html