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

之前生产变更产生的后遗症,就是需要去读取日志并且筛选出其中的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;
    }

13566833-f28d2d86e232ba7e.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值