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;
    }
可执行脚本文件.png

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,646评论 4 366
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,979评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,391评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,356评论 0 215
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,740评论 3 293
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,836评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,022评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,764评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,487评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,728评论 2 252
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,200评论 1 263
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,548评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,217评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,134评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,921评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,919评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,766评论 2 274

推荐阅读更多精彩内容