(12)多线程的运用(2)---- 读取db文件,解析数据入MySql 数据库【源码】

原文:https://blog.csdn.net/tangthh123/article/details/105854438

整个读取db文件的源码如下:

(1)Controller

注意:

这边我采用了异步调用的方法,因为300MB的文件解析下来需要200S ,如果前端一直访问我这个接口没用返回数据的话,直接network上报error.

异步调用原理很简单,前端调用这个接口以后,立马返回数据,后端开启一个线程去执行我解析文件的代码。

如何开启异步调用?

 小编用的是SpringBoot,第一步是需要在启动类上加上@EnableAsync

其次需要在具体的方法上加上 @Async 

 /**
     * 4.导入本地文本文件(.txt 或者db文件)解析文件数据,将其保存到数据库中
     *
     * @param
     * @return
     */
    @RequestMapping(value = "/uploadFileToNasLog")
    public ResultData uploadFileToNasLog(@RequestParam("uploadFile") MultipartFile file,HttpServletRequest request) {
        ResultData resultData = new ResultData();
        NasLogVo vo = new NasLogVo();
        vo.setFile(file);
        vo.setType("1");
        vo.setRequest(request);

        //获取上传的文件名称
        String fileName = file.getOriginalFilename();
        //上传文件功能
        String rootPath = request.getServletContext().getRealPath("upload");
        File fileTemp = new File(rootPath);
        if (!fileTemp.exists()) {
            fileTemp.exists();
        }
        String fileUrl = rootPath + "\\" + fileName;
        vo.setPath(fileUrl);
        vo.setFileName(fileName);
        File file1 = new File(fileUrl);
        try {
            file.transferTo(file1);
        } catch (IOException e) {
            e.printStackTrace();
        }

        DeferredResult<ResultData> deferredResult = new DeferredResult<>();
        CompletableFuture.supplyAsync(()->nasService.uploadFileToNasLog(vo))
                .whenCompleteAsync((result, throwable) -> deferredResult.setResult(result));

        return resultData ;
    }

(2)NasService

 /**
     * 6.上传文本文件,数据保存在群晖日志表中
     *
     * @param
     * @return
     */
    @Override
    @Async
    public ResultData uploadFileToNasLog(NasLogVo vo) {
        ResultData resultData = new ResultData();
        Map<String, File> map = new HashMap<String, File>();
        String fileUrl = vo.getPath();
        String fileName = vo.getFileName();
        long startTime = System.currentTimeMillis();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("开始时间----" + simpleDateFormat.format(new Date()));
        try {

            //将上传的文件信息保存到nas_file ,以备后期删除这些临时文件数据
            NasFileModel nasFileModel = new NasFileModel();
            nasFileModel.setFileName(fileName);
            nasFileModel.setFileUrl(fileUrl);
            inserDateToNasFile(nasFileModel);

                Builder builder = new Builder(fileUrl, new IHandle() {
                    @Override
                    public void handle(String line) {

                    }
                });
                builder.withTreahdSize(10)
                        .withCharset("gbk")
                        .withBufferSize(1024 * 1024)
                        .withFilePath(fileUrl);

                BigFileReader bigFileReader = builder.build();
                bigFileReader.start();
        
            resultData.setResult("true");
            resultData.setMessage("上传成功");

            long endTime1 = System.currentTimeMillis();
            float excTime = (float) (endTime1 - startTime) / 1000;
            System.out.println("执行DB文件时间:" + excTime + "s");


        } catch (Exception e) {
            logger.error("文件上传失败", e);
            resultData.setResult("false");
            resultData.setMessage("上传失败");
        }
        return resultData;
    }

(3)读取db文件的方法

 class BigFileReader {
        private int threadSize;
        private String charset;
        private int bufferSize;
        private IHandle handle;
        ExecutorService executorService;
        private long fileLength;
        RandomAccessFile rAccessFile;
        Set<StartEndPair> startEndPairs;
        CyclicBarrier cyclicBarrier;
        AtomicLong counter = new AtomicLong(0);
        private String filePath;

        private BigFileReader(File file, IHandle handle, String charset, int bufferSize, int threadSize, String filePath) {
            this.fileLength = file.length();
            this.handle = handle;
            this.charset = charset;
            this.bufferSize = bufferSize;
            this.threadSize = threadSize;
            this.filePath = filePath;
            try {

                this.rAccessFile = new RandomAccessFile(file, "r");

                String url = SqliteUtil.DB_URL.replace("{url}", filePath);
                Connection connection = SqliteUtil.createConnection(url);
                //解析db文件中的数据
                //执行当前线程
                Statement statement = connection.createStatement();
                // 执行查询语句
                ResultSet rs = statement.executeQuery("select * from logs");
                List<NasSynologyModel> nasSynologyModelList = new ArrayList<>();
                while (rs.next()) {
                    NasSynologyModel synologyModel = new NasSynologyModel();
                    synologyModel.setHost(rs.getString("host"));
                    synologyModel.setIp(rs.getString("ip"));
                    synologyModel.setFac(rs.getString("fac"));
                    synologyModel.setPrio(rs.getString("prio"));
                    synologyModel.setLlevel(rs.getString("llevel"));
                    synologyModel.setTag(rs.getString("tag"));
                    synologyModel.setUtcsec(rs.getString("utcsec"));
                    synologyModel.setrUtcsec(rs.getString("r_utcsec"));
                    synologyModel.setTzoffset(rs.getString("tzoffset"));
                    synologyModel.setLdate(rs.getString("ldate"));
                    synologyModel.setLtime(rs.getString("ltime"));
                    synologyModel.setProg(rs.getString("prog"));
                    synologyModel.setMsg(rs.getString("msg"));
                    nasSynologyModelList.add(synologyModel);

                }
                //使用jdbc 的保存
                insertNasSynologyByJdpcTemplate(nasSynologyModelList);
                //保存完当前这个项目文件以后删除上传的文件

            } catch (Exception e) {
                System.err.println(e.getMessage());
            }

            this.executorService = Executors.newFixedThreadPool(threadSize);
            startEndPairs = new HashSet<StartEndPair>();
        }

        public void start() {
            long everySize = this.fileLength / this.threadSize;
            try {
                calculateStartEnd(0, everySize);
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }

            final long startTime = System.currentTimeMillis();
            cyclicBarrier = new CyclicBarrier(startEndPairs.size(), new Runnable() {

                @Override
                public void run() {
                }
            });

            for (StartEndPair pair : startEndPairs) {
                this.executorService.execute(new SliceReaderTask(pair));
            }
        }

        private void calculateStartEnd(long start, long size) throws IOException {
            if (start > fileLength - 1) {
                return;
            }
            StartEndPair pair = new StartEndPair();
            pair.start = start;
            long endPosition = start + size - 1;
            if (endPosition >= fileLength - 1) {
                pair.end = fileLength - 1;
                startEndPairs.add(pair);
                return;
            }

            rAccessFile.seek(endPosition);
            byte tmp = (byte) rAccessFile.read();
            while (tmp != '\n' && tmp != '\r') {
                endPosition++;
                if (endPosition >= fileLength - 1) {
                    endPosition = fileLength - 1;
                    break;
                }
                rAccessFile.seek(endPosition);
                tmp = (byte) rAccessFile.read();
            }
            pair.end = endPosition;
            startEndPairs.add(pair);

            calculateStartEnd(endPosition + 1, size);

        }


        private void handle(byte[] bytes) throws UnsupportedEncodingException {
            String line = null;
            if (this.charset == null) {
                line = new String(bytes);
            } else {
                line = new String(bytes, charset);
            }
            if (line != null && !"".equals(line)) {
                this.handle.handle(line);
                counter.incrementAndGet();
            }
        }

        private class StartEndPair {
            public long start;
            public long end;

            @Override
            public String toString() {
                return "star=" + start + ";end=" + end;
            }

            @Override
            public int hashCode() {
                final int prime = 31;
                int result = 1;
                result = prime * result + (int) (end ^ (end >>> 32));
                result = prime * result + (int) (start ^ (start >>> 32));
                return result;
            }

            @Override
            public boolean equals(Object obj) {
                if (this == obj) {
                    return true;
                }

                if (obj == null) {
                    return false;
                }

                if (getClass() != obj.getClass()) {
                    return false;
                }
                StartEndPair other = (StartEndPair) obj;
                if (end != other.end) {
                    return false;
                }
                if (start != other.start) {
                    return false;
                }
                return true;
            }

        }

        private class SliceReaderTask implements Runnable {
            private long start;
            private long sliceSize;
            private byte[] readBuff;

            public SliceReaderTask(StartEndPair pair) {
                this.start = pair.start;
                this.sliceSize = pair.end - pair.start + 1;
                this.readBuff = new byte[bufferSize];
            }

            @Override
            public void run() {
                try {

                    MappedByteBuffer mapBuffer = rAccessFile.getChannel().map(FileChannel.MapMode.READ_ONLY, start, this.sliceSize);
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    for (int offset = 0; offset < sliceSize; offset += bufferSize) {
                        int readLength;
                        if (offset + bufferSize <= sliceSize) {
                            readLength = bufferSize;
                        } else {
                            readLength = (int) (sliceSize - offset);
                        }
                        mapBuffer.get(readBuff, 0, readLength);
                        for (int i = 0; i < readLength; i++) {
                            byte tmp = readBuff[i];
                            if (tmp == '\n' || tmp == '\r') {
                                handle(bos.toByteArray());
                                bos.reset();
                            } else {
                                bos.write(tmp);
                            }
                        }
                    }
                    if (bos.size() > 0) {
                        handle(bos.toByteArray());
                    }
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }


    }

(4)具体连接Sqlite数据库的方法(SqliteUtil)

package com.bos.common.file;

import java.sql.*;

/**
 * @Author: tanghh
 * Java操作Sqlite数据库
 */
public class SqliteUtil {
    private static final String Class_Name = "org.sqlite.JDBC";
    /**
     * 要组成这样的url:   jdbc:sqlite:C://uploadFile/NasLog/2019-04-03_2019-04-12.DB
     */
    public static String DB_URL = "jdbc:sqlite:{url}";

    /**
     * 测试连接sqlite数据库的方法
     * @param
     * @return
     */
    public static void main(String[] args) {
        String url = "jdbc:sqlite:C://uploadFile/NasLog/2019-04-03_2019-04-12.DB";
        connectSqlite(url);

    }


    public static void connectSqlite(String url) {
        Connection connection = null;
        try {
            connection = createConnection(url);
            func1(connection);
        } catch (SQLException e) {
            System.err.println(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (connection != null)
                    connection.close();
            } catch (SQLException e) {
                // connection close failed.
                System.err.println(e);
            }
        }


    }


    /**
     * 创建Sqlite数据库连接
     *
     * @param
     * @return
     */
    public static Connection createConnection(String url) throws SQLException, ClassNotFoundException {
        Class.forName(Class_Name);
        return DriverManager.getConnection(url);
    }

    public static void func1(Connection connection) throws SQLException {
        Statement statement = connection.createStatement();
        // set timeout to 30 sec.
        statement.setQueryTimeout(30);
        // 执行查询语句
        ResultSet rs = statement.executeQuery("select * from logs limit 100");
        while (rs.next()) {
            String host = rs.getString("host");
            String ip = rs.getString("ip");
            String fac = rs.getString("fac");
            String prio = rs.getString("prio");
            String llevel = rs.getString("llevel");
            String tag = rs.getString("tag");
            String utcsec = rs.getString("utcsec");
            String r_utcsec = rs.getString("r_utcsec");
            String ldate = rs.getString("ldate");
            String ltime = rs.getString("ltime");
            String prog = rs.getString("prog");
            String msg = rs.getString("msg");
            System.out.println("host = " + host + "  ip = " + ip);
            // 执行插入语句操作
            statement.executeUpdate("insert into nas_log(server_name,ip_address,user_name,type,time) values(host,ip,fac,info,ltime)");
            // 执行更新语句
//            statement1.executeUpdate("update table_name2 set 字段名1=" +  字段值1 + " where 字段名2='" +  字段值2 + "'");
        }
    }
}

(5) NasLogVo

package com.bos.data.model.vo.setting;

import lombok.Data;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author: tanghh
 * 群晖Nas
 */
public @Data
class NasLogVo {
    private String Event;
    private String Path;
    private String Size;
    private String User;
    private String IP;

    /**
     * 群晖Nas上传的文件
     * @param
     * @return
     */
    private MultipartFile file;

    /**
     * 文件上传类型  0为.txt 文件  1为db文件
     * @param
     * @return
     */
    private String type;

    private HttpServletRequest request;

    private String fileName;
}

(6)保存数据的方法

  /**
     * 将数据通过jdbcTemplate的方式保存到数据库中
     *
     * @param nasSynologyModelList
     * @return
     */
    private int insertNasSynologyByJdpcTemplate(List<NasSynologyModel> nasSynologyModelList) {
        String sql = "insert into nas_synology(host,ip,fac,prio,llevel,tag,utcsec,r_utcsec,tzoffset,ldate,ltime,prog,msg,is_analysis) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";

        try {
            jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
                @Override
                public void setValues(PreparedStatement ps, int i) throws SQLException {
                    ps.setString(1, nasSynologyModelList.get(i).getHost());
                    ps.setString(2, nasSynologyModelList.get(i).getIp());
                    ps.setString(3, nasSynologyModelList.get(i).getFac());
                    ps.setString(4, nasSynologyModelList.get(i).getPrio());
                    ps.setString(5, nasSynologyModelList.get(i).getLlevel());
                    ps.setString(6, nasSynologyModelList.get(i).getTag());
                    ps.setString(7, nasSynologyModelList.get(i).getUtcsec());
                    ps.setString(8, nasSynologyModelList.get(i).getrUtcsec());
                    ps.setString(9, nasSynologyModelList.get(i).getTzoffset());
                    ps.setString(10, nasSynologyModelList.get(i).getLdate());
                    ps.setString(11, nasSynologyModelList.get(i).getLtime());
                    ps.setString(12, nasSynologyModelList.get(i).getProg());
                    ps.setString(13, nasSynologyModelList.get(i).getMsg());
                    ps.setString(14, "0");
                }

                @Override
                public int getBatchSize() {
                    return nasSynologyModelList.size();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

(7)Builder类

 class Builder {
        private int threadSize = 1;
        private String charset = null;
        private int bufferSize = 1024 * 1024;
        private IHandle handle;
        private File file;
        private String filePath;

        public Builder(String file, IHandle handle) {
            this.file = new File(file);
            if (!this.file.exists()) {
                throw new IllegalArgumentException("文件不存在!");
            }
            this.handle = handle;
        }


        public Builder withTreahdSize(int size) {
            this.threadSize = size;
            return this;
        }

        public Builder withCharset(String charset) {
            this.charset = charset;
            return this;
        }

        public Builder withBufferSize(int bufferSize) {
            this.bufferSize = bufferSize;
            return this;
        }

        public Builder withFilePath(String filePath) {
            this.filePath = filePath;
            return this;
        }

        public BigFileReader build() {
            return new BigFileReader(this.file, this.handle, this.charset, this.bufferSize, this.threadSize, this.filePath);
        }
    }

(8)NasFileModel 

package com.bos.data.model;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Objects;

/**
 * @Author tanghh
 * @Date 2020/4/23 16:02
 */
@Entity
@Table(name = "nas_file", schema = "test3", catalog = "")
public class NasFileModel {
    private int id;
    private String fileName;
    private String fileUrl;
    private Timestamp createTime;
    private String isDel;

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Basic
    @Column(name = "file_name")
    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    @Basic
    @Column(name = "file_url")
    public String getFileUrl() {
        return fileUrl;
    }

    public void setFileUrl(String fileUrl) {
        this.fileUrl = fileUrl;
    }

    @Basic
    @Column(name = "create_time")
    public Timestamp getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Timestamp createTime) {
        this.createTime = createTime;
    }

    @Basic
    @Column(name = "is_del")
    public String getIsDel() {
        return isDel;
    }

    public void setIsDel(String isDel) {
        this.isDel = isDel;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        NasFileModel that = (NasFileModel) o;
        return id == that.id &&
                Objects.equals(fileName, that.fileName) &&
                Objects.equals(fileUrl, that.fileUrl) &&
                Objects.equals(createTime, that.createTime) &&
                Objects.equals(isDel, that.isDel);
    }

    @Override
    public int hashCode() {

        return Objects.hash(id, fileName, fileUrl, createTime, isDel);
    }
}

(9)NasSynologyModel

package com.bos.data.model;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Objects;

/**
 * @Author tanghh
 * @Date 2020/4/22 8:52
 */
@Entity
@Table(name = "nas_synology", schema = "test3", catalog = "")
public class NasSynologyModel {
    private int id;
    private String host;
    private String ip;
    private String fac;
    private String prio;
    private String llevel;
    private String tag;
    private String utcsec;
    private String rUtcsec;
    private String tzoffset;
    private String ldate;
    private String ltime;
    private String prog;
    private String msg;
    private Timestamp createTime;
    private String isAnalysis="0";

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Basic
    @Column(name = "host")
    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    @Basic
    @Column(name = "ip")
    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    @Basic
    @Column(name = "fac")
    public String getFac() {
        return fac;
    }

    public void setFac(String fac) {
        this.fac = fac;
    }

    @Basic
    @Column(name = "prio")
    public String getPrio() {
        return prio;
    }

    public void setPrio(String prio) {
        this.prio = prio;
    }

    @Basic
    @Column(name = "llevel")
    public String getLlevel() {
        return llevel;
    }

    public void setLlevel(String llevel) {
        this.llevel = llevel;
    }

    @Basic
    @Column(name = "tag")
    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    @Basic
    @Column(name = "utcsec")
    public String getUtcsec() {
        return utcsec;
    }

    public void setUtcsec(String utcsec) {
        this.utcsec = utcsec;
    }

    @Basic
    @Column(name = "r_utcsec")
    public String getrUtcsec() {
        return rUtcsec;
    }

    public void setrUtcsec(String rUtcsec) {
        this.rUtcsec = rUtcsec;
    }

    @Basic
    @Column(name = "tzoffset")
    public String getTzoffset() {
        return tzoffset;
    }

    public void setTzoffset(String tzoffset) {
        this.tzoffset = tzoffset;
    }

    @Basic
    @Column(name = "ldate")
    public String getLdate() {
        return ldate;
    }

    public void setLdate(String ldate) {
        this.ldate = ldate;
    }

    @Basic
    @Column(name = "ltime")
    public String getLtime() {
        return ltime;
    }

    public void setLtime(String ltime) {
        this.ltime = ltime;
    }

    @Basic
    @Column(name = "prog")
    public String getProg() {
        return prog;
    }

    public void setProg(String prog) {
        this.prog = prog;
    }

    @Basic
    @Column(name = "msg")
    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    @Basic
    @Column(name = "create_time")
    public Timestamp getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Timestamp createTime) {
        this.createTime = createTime;
    }
    @Basic
    @Column(name = "is_analysis")
    public String getIsAnalysis() {
        return isAnalysis;
    }

    public void setIsAnalysis(String isAnalysis) {
        this.isAnalysis = isAnalysis;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        NasSynologyModel that = (NasSynologyModel) o;
        return id == that.id &&
                Objects.equals(host, that.host) &&
                Objects.equals(ip, that.ip) &&
                Objects.equals(fac, that.fac) &&
                Objects.equals(prio, that.prio) &&
                Objects.equals(llevel, that.llevel) &&
                Objects.equals(tag, that.tag) &&
                Objects.equals(utcsec, that.utcsec) &&
                Objects.equals(rUtcsec, that.rUtcsec) &&
                Objects.equals(tzoffset, that.tzoffset) &&
                Objects.equals(ldate, that.ldate) &&
                Objects.equals(ltime, that.ltime) &&
                Objects.equals(prog, that.prog) &&
                Objects.equals(msg, that.msg);
    }

    @Override
    public int hashCode() {

        return Objects.hash(id, host, ip, fac, prio, llevel, tag, utcsec, rUtcsec, tzoffset, ldate, ltime, prog, msg);
    }
}

(10)ResultData

package com.bos.common;

import com.bos.data.model.TShowColumnModel;
import io.swagger.annotations.ApiModelProperty;

import java.util.List;
import java.util.Map;

/**
 * @author luoj
 * @author luojie 2018/6/8
 */
public class ResultData {
    /**
     * "true" or "false"
     */
    @ApiModelProperty(value = "后台返回的查询结果,true=查询成功,false=查询失败")
    private String result;
    /**
     * 消息提示
     */
    @ApiModelProperty(value = "后台返回的消息,如'保存成功'。用作前端的提示消息")
    private String message;

    /**
     * 消息提示
     */
    @ApiModelProperty(value = "一个字符串")
    private String str;

    /**
     * 存放一个实体
     */
    private Object object;
    /**
     * 主数据集合
     */
    private PageData pageData;
    /**
     *其他数据
     */
    private List<Map> otherData;
    /**
     *整形
     */
    private Integer number;
    /**
     *存放list集合的map
     */
    private Map<String, List> mapList;
    /**
     *
     */
    private Map<Object, Object> map;
    /**
     *存放一个list集合
     */
    private List list;
    /**
     *专用于存放表头字段的集合
     */
    private List fieldList;
    /**
     *专用于存放视图集合
     */
    private List viewList;

    /**
     *专用于存放报表集合
     */
    private List reportList;

    /**
     * 专用于存每个页面的page
     * @param
     * @return
     */
    private String page;
    /**
     * 专用于存不同页面的module
     * @param
     * @return
     */
    private String module;

    /**
     * 存储当前数据的上一级数据(第一级)
     * @param
     * @return
     */
    private String level1;
    /**
     * 存储当前数据的上一级的上一级数据(第二级)
     * @param
     * @return
     */
    private String level2;
    /**
     * 存储当前数据的上一级的上一级的上一级数据(第三级)
     * @param
     * @return
     */
    private String level3;

    /**
     * map2
     */
    private Map<Object, Object> map2;

    private Map<String,List<TShowColumnModel>> mapCloumnList;

    public List getReportList() {
        return reportList;
    }

    public void setReportList(List reportList) {
        this.reportList = reportList;
    }

    public List getViewList() {
        return viewList;
    }

    public void setViewList(List viewList) {
        this.viewList = viewList;
    }

    public List getList() {
        return list;
    }

    public void setList(List list) {
        this.list = list;
    }

    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }

    public Map<String, List<TShowColumnModel>> getMapCloumnList() {
        return mapCloumnList;
    }

    public void setMapCloumnList(Map<String, List<TShowColumnModel>> mapCloumnList) {
        this.mapCloumnList = mapCloumnList;
    }

    public ResultData() {
        this.message = "查询成功";
        this.result = "true";
    }

    /**
     * 用于删除成功
     * @param count
     */
    public ResultData(int count) {
        if(count>0){
            this.message = "删除成功";
            this.result = "true";
        }else {
            this.message = "删除失败";
            this.result = "false";
        }
    }

    public ResultData(Object object) {
        this.object=object;
        this.message = "查询成功";
        this.result = "true";
    }

    /**
     * 用于添加删除提示
     * @param type
     * @param flag
     */
    public ResultData(String type,boolean flag) {
        if(flag==false){
            //保存和修改时候的提示
            if(Constant.SAVE.equals(type)){
                this.message = "保存失败";
            }else{
                this.message = "删除失败";
            }
            this.result = "false";
        }else {
            if(Constant.SAVE.equals(type)){
                this.message = "保存成功";
            }else{
                this.message = "删除成功";
            }
            this.result = "true";
        }
    }

    public ResultData(String result, String message, PageData pageData) {
        this.result = result;
        this.message = message;
        this.pageData = pageData;
    }

    public ResultData(String result, String message, PageData pageData, List<Map> otherData) {
        this.result = result;
        this.message = message;
        this.pageData = pageData;
        this.otherData = otherData;
    }

    public ResultData(String result, String message, PageData pageData, List<Map> otherData, Map<String, List> mapList) {
        this.result = result;
        this.message = message;
        this.pageData = pageData;
        this.otherData = otherData;
        this.mapList = mapList;
    }

    public ResultData(String result, String message) {
        this.result = result;
        this.message = message;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public PageData getPageData() {
        return pageData;
    }

    public void setPageData(PageData pageData) {
        this.pageData = pageData;
    }

    public List<Map> getOtherData() {
        return otherData;
    }

    public void setOtherData(List<Map> otherData) {
        this.otherData = otherData;
    }

    public Map<String, List> getMapList() {
        return mapList;
    }

    public void setMapList(Map<String, List> mapList) {
        this.mapList = mapList;
    }

    public Map<Object, Object> getMap() {
        return map;
    }

    public void setMap(Map<Object, Object> map) {
        this.map = map;
    }

    public List getFieldList() {
        return fieldList;
    }

    public void setFieldList(List fieldList) {
        this.fieldList = fieldList;
    }

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    public String getPage() {
        return page;
    }

    public void setPage(String page) {
        this.page = page;
    }

    public String getModule() {
        return module;
    }

    public void setModule(String module) {
        this.module = module;
    }

    public String getLevel1() {
        return level1;
    }

    public void setLevel1(String level1) {
        this.level1 = level1;
    }

    public String getLevel2() {
        return level2;
    }

    public void setLevel2(String level2) {
        this.level2 = level2;
    }

    public String getLevel3() {
        return level3;
    }

    public void setLevel3(String level3) {
        this.level3 = level3;
    }

    public Map<Object, Object> getMap2() {
        return map2;
    }

    public void setMap2(Map<Object, Object> map2) {
        this.map2 = map2;
    }
}

(11)整个NasService

package com.bos.service.impl.basic;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bos.common.PageData;
import com.bos.common.ResultData;
import com.bos.common.file.FileThreadResource;
import com.bos.common.file.FileUtil;
import com.bos.common.file.IHandle;
import com.bos.common.file.SqliteUtil;
import com.bos.data.model.NasFileModel;
import com.bos.data.model.NasLogModel;
import com.bos.data.model.NasSynologyModel;
import com.bos.data.model.vo.basic.CommonVO;
import com.bos.data.model.vo.setting.NASVo;
import com.bos.data.model.vo.setting.NasLogVo;
import com.bos.data.repositories.ColumnRepository;
import com.bos.data.repositories.NasLogRepository;
import com.bos.data.repositories.jpa.NasFileJPARepository;
import com.bos.data.repositories.jpa.NasLogJPARepository;
import com.bos.data.repositories.jpa.NasSynologyJPARepository;
import com.bos.service.basic.CommonService;
import com.bos.service.basic.NASService;
import com.bos.service.integrated_management.BosUserService;
import com.bos.util.DateUtil;
import com.bos.util.FastDFSClientWrapper;
import com.bos.util.NasUtil;
import com.bos.util.SendRequest;
import com.google.common.base.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.transaction.Transactional;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.sql.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Date;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author luojie on 2018/11/30
 */
@Service
@Transactional(rollbackOn = Exception.class)
public class NASServiceImpl implements NASService {
    private Logger logger = LoggerFactory.getLogger(NASServiceImpl.class);


    @Autowired
    private NasLogJPARepository nasLogJPARepository;

    @Autowired
    private NasLogRepository nasLogRepository;


  
    @Autowired
    private NasSynologyJPARepository nasSynologyJPARepository;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private NasFileJPARepository nasFileJPARepository;


  


   

   

   

    /**
     * 将数据通过jdbcTemplate的方式保存到数据库中
     *
     * @param nasSynologyModelList
     * @return
     */
    private int insertNasSynologyByJdpcTemplate(List<NasSynologyModel> nasSynologyModelList) {
        String sql = "insert into nas_synology(host,ip,fac,prio,llevel,tag,utcsec,r_utcsec,tzoffset,ldate,ltime,prog,msg,is_analysis) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";

        try {
            jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
                @Override
                public void setValues(PreparedStatement ps, int i) throws SQLException {
                    ps.setString(1, nasSynologyModelList.get(i).getHost());
                    ps.setString(2, nasSynologyModelList.get(i).getIp());
                    ps.setString(3, nasSynologyModelList.get(i).getFac());
                    ps.setString(4, nasSynologyModelList.get(i).getPrio());
                    ps.setString(5, nasSynologyModelList.get(i).getLlevel());
                    ps.setString(6, nasSynologyModelList.get(i).getTag());
                    ps.setString(7, nasSynologyModelList.get(i).getUtcsec());
                    ps.setString(8, nasSynologyModelList.get(i).getrUtcsec());
                    ps.setString(9, nasSynologyModelList.get(i).getTzoffset());
                    ps.setString(10, nasSynologyModelList.get(i).getLdate());
                    ps.setString(11, nasSynologyModelList.get(i).getLtime());
                    ps.setString(12, nasSynologyModelList.get(i).getProg());
                    ps.setString(13, nasSynologyModelList.get(i).getMsg());
                    ps.setString(14, "0");
                }

                @Override
                public int getBatchSize() {
                    return nasSynologyModelList.size();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }


    

    /**
     * 6.上传文本文件,数据保存在群晖日志表中
     *
     * @param
     * @return
     */
    @Override
    @Async
    public ResultData uploadFileToNasLog(NasLogVo vo) {
        ResultData resultData = new ResultData();
        Map<String, File> map = new HashMap<String, File>();
        String fileUrl = vo.getPath();
        String fileName = vo.getFileName();
        long startTime = System.currentTimeMillis();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("开始时间----" + simpleDateFormat.format(new Date()));
        try {

            //将上传的文件信息保存到nas_file ,以备后期删除这些临时文件数据
            NasFileModel nasFileModel = new NasFileModel();
            nasFileModel.setFileName(fileName);
            nasFileModel.setFileUrl(fileUrl);
            inserDateToNasFile(nasFileModel);

            //将上传的文件信息保存到
            if (vo.getType().equals("0")) {
                FileUtil fileUtil = new FileUtil();
                // 如果当前上传的文件为.txt文件, 接下来将这个大文件分割成多个小文件(提高解析文本行的效率)
                fileUtil.readFile(fileUrl);
                //接下来遍历整个文件夹里的31个分割后的文件
                File[] files = new File(fileUrl).listFiles();
                for (File fileInfo : files) {
                    if (fileInfo.isFile() && fileInfo.exists() && fileInfo.getName().contains("part")) {
                        fileName = fileInfo.getName();
                        map.put(fileName, fileInfo);
                    }
                }
                //创建自定义线程对象(开启10个线程来解析这三十一个文件)
                FileThreadResource resource = new FileThreadResource();
                for (int k = 0; k < 10; k++) {
                    FileThread mt = new FileThread(fileName, map, resource);
                    mt.run();
                }

            } else {

                Builder builder = new Builder(fileUrl, new IHandle() {
                    @Override
                    public void handle(String line) {

                    }
                });
                builder.withTreahdSize(10)
                        .withCharset("gbk")
                        .withBufferSize(1024 * 1024)
                        .withFilePath(fileUrl);

                BigFileReader bigFileReader = builder.build();
                bigFileReader.start();
            }
            resultData.setResult("true");
            resultData.setMessage("上传成功");

            long endTime1 = System.currentTimeMillis();
            float excTime = (float) (endTime1 - startTime) / 1000;
            System.out.println("执行DB文件时间:" + excTime + "s");


        } catch (Exception e) {
            logger.error("文件上传失败", e);
            resultData.setResult("false");
            resultData.setMessage("上传失败");
        }
        return resultData;
    }


  
    /**
     * 7.保存群晖日志文件数据
     *
     * @param
     * @return
     */
    @Override
    public void insertDataToNasLog(NasLogModel nasLogModel) {
        try {
            nasLogJPARepository.save(nasLogModel);
        } catch (Exception e) {
            logger.error("保存群晖日志信息失败", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    @Override
    public void inserDateToNasFile(NasFileModel nasFileModel) {
        try {
            nasFileJPARepository.save(nasFileModel);
        } catch (Exception e) {
            logger.error("保存群晖日志信息失败", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

   

    @Override
    public void insertAllDataToNasLogByJdbcTemplate(List<NasLogModel> nasLogModelList) {
        String sql = "insert into nas_log(type,logs,time,ip,user_name,event,floder,file_size,file_name,ip_address,is_del,call_name,level,flevel1,flevel2,flevel3,flevel4,flevel5,flevel6,flevel7,flevel8,flevel9,flevel10,flevel_number,specific_name) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        try {
            jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
                @Override
                public void setValues(PreparedStatement ps, int i) throws SQLException {
                    ps.setString(1, nasLogModelList.get(i).getType());
                    ps.setString(2, nasLogModelList.get(i).getLogs());
                    ps.setString(3, nasLogModelList.get(i).getTime());
                    ps.setString(4, nasLogModelList.get(i).getIp());
                    ps.setString(5, nasLogModelList.get(i).getUserName());
                    ps.setString(6, nasLogModelList.get(i).getEvent());
                    ps.setString(7, nasLogModelList.get(i).getFloder());
                    ps.setString(8, nasLogModelList.get(i).getFileSize());
                    ps.setString(9, nasLogModelList.get(i).getFileName());
                    ps.setString(10, nasLogModelList.get(i).getIpAddress());
                    ps.setString(11, "0");
                    ps.setString(12, nasLogModelList.get(i).getCallName());
                    ps.setString(13, nasLogModelList.get(i).getLevel());
                    ps.setString(14, nasLogModelList.get(i).getFlevel1());
                    ps.setString(15, nasLogModelList.get(i).getFlevel2());
                    ps.setString(16, nasLogModelList.get(i).getFlevel3());
                    ps.setString(17, nasLogModelList.get(i).getFlevel4());
                    ps.setString(18, nasLogModelList.get(i).getFlevel5());
                    ps.setString(19, nasLogModelList.get(i).getFlevel6());
                    ps.setString(20, nasLogModelList.get(i).getFlevel7());
                    ps.setString(21, nasLogModelList.get(i).getFlevel8());
                    ps.setString(22, nasLogModelList.get(i).getFlevel9());
                    ps.setString(23, nasLogModelList.get(i).getFlevel10());
                    ps.setInt(24, nasLogModelList.get(i).getFlevelNumber());
                    ps.setString(25, nasLogModelList.get(i).getSpecificName());
                }

                @Override
                public int getBatchSize() {
                    return nasLogModelList.size();
                }

            });
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

   

    /**
     * 根据文件名称和文件路径删除文件
     * @param filename
     * @param filePath
     * @return
     */
    public boolean deleteFile(String filename,String filePath){
        File file = new File(filePath);
        // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                return true;
            } else {
                return false;
            }
        } else {
            file.delete();
            return true;
        }
    } 

    
    class BigFileReader {
        private int threadSize;
        private String charset;
        private int bufferSize;
        private IHandle handle;
        ExecutorService executorService;
        private long fileLength;
        RandomAccessFile rAccessFile;
        Set<StartEndPair> startEndPairs;
        CyclicBarrier cyclicBarrier;
        AtomicLong counter = new AtomicLong(0);
        private String filePath;

        private BigFileReader(File file, IHandle handle, String charset, int bufferSize, int threadSize, String filePath) {
            this.fileLength = file.length();
            this.handle = handle;
            this.charset = charset;
            this.bufferSize = bufferSize;
            this.threadSize = threadSize;
            this.filePath = filePath;
            try {

                this.rAccessFile = new RandomAccessFile(file, "r");

                String url = SqliteUtil.DB_URL.replace("{url}", filePath);
                Connection connection = SqliteUtil.createConnection(url);
                //解析db文件中的数据
                //执行当前线程
                Statement statement = connection.createStatement();
                // 执行查询语句
                ResultSet rs = statement.executeQuery("select * from logs");
                List<NasSynologyModel> nasSynologyModelList = new ArrayList<>();
                while (rs.next()) {
                    NasSynologyModel synologyModel = new NasSynologyModel();
                    synologyModel.setHost(rs.getString("host"));
                    synologyModel.setIp(rs.getString("ip"));
                    synologyModel.setFac(rs.getString("fac"));
                    synologyModel.setPrio(rs.getString("prio"));
                    synologyModel.setLlevel(rs.getString("llevel"));
                    synologyModel.setTag(rs.getString("tag"));
                    synologyModel.setUtcsec(rs.getString("utcsec"));
                    synologyModel.setrUtcsec(rs.getString("r_utcsec"));
                    synologyModel.setTzoffset(rs.getString("tzoffset"));
                    synologyModel.setLdate(rs.getString("ldate"));
                    synologyModel.setLtime(rs.getString("ltime"));
                    synologyModel.setProg(rs.getString("prog"));
                    synologyModel.setMsg(rs.getString("msg"));
                    nasSynologyModelList.add(synologyModel);

                }
                //使用jdbc 的保存
                insertNasSynologyByJdpcTemplate(nasSynologyModelList);
                //保存完当前这个项目文件以后删除上传的文件

            } catch (Exception e) {
                System.err.println(e.getMessage());
            }

            this.executorService = Executors.newFixedThreadPool(threadSize);
            startEndPairs = new HashSet<StartEndPair>();
        }

        public void start() {
            long everySize = this.fileLength / this.threadSize;
            try {
                calculateStartEnd(0, everySize);
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }

            final long startTime = System.currentTimeMillis();
            cyclicBarrier = new CyclicBarrier(startEndPairs.size(), new Runnable() {

                @Override
                public void run() {
                }
            });

            for (StartEndPair pair : startEndPairs) {
                this.executorService.execute(new SliceReaderTask(pair));
            }
        }

        private void calculateStartEnd(long start, long size) throws IOException {
            if (start > fileLength - 1) {
                return;
            }
            StartEndPair pair = new StartEndPair();
            pair.start = start;
            long endPosition = start + size - 1;
            if (endPosition >= fileLength - 1) {
                pair.end = fileLength - 1;
                startEndPairs.add(pair);
                return;
            }

            rAccessFile.seek(endPosition);
            byte tmp = (byte) rAccessFile.read();
            while (tmp != '\n' && tmp != '\r') {
                endPosition++;
                if (endPosition >= fileLength - 1) {
                    endPosition = fileLength - 1;
                    break;
                }
                rAccessFile.seek(endPosition);
                tmp = (byte) rAccessFile.read();
            }
            pair.end = endPosition;
            startEndPairs.add(pair);

            calculateStartEnd(endPosition + 1, size);

        }


        private void handle(byte[] bytes) throws UnsupportedEncodingException {
            String line = null;
            if (this.charset == null) {
                line = new String(bytes);
            } else {
                line = new String(bytes, charset);
            }
            if (line != null && !"".equals(line)) {
                this.handle.handle(line);
                counter.incrementAndGet();
            }
        }

        private class StartEndPair {
            public long start;
            public long end;

            @Override
            public String toString() {
                return "star=" + start + ";end=" + end;
            }

            @Override
            public int hashCode() {
                final int prime = 31;
                int result = 1;
                result = prime * result + (int) (end ^ (end >>> 32));
                result = prime * result + (int) (start ^ (start >>> 32));
                return result;
            }

            @Override
            public boolean equals(Object obj) {
                if (this == obj) {
                    return true;
                }

                if (obj == null) {
                    return false;
                }

                if (getClass() != obj.getClass()) {
                    return false;
                }
                StartEndPair other = (StartEndPair) obj;
                if (end != other.end) {
                    return false;
                }
                if (start != other.start) {
                    return false;
                }
                return true;
            }

        }

        private class SliceReaderTask implements Runnable {
            private long start;
            private long sliceSize;
            private byte[] readBuff;

            public SliceReaderTask(StartEndPair pair) {
                this.start = pair.start;
                this.sliceSize = pair.end - pair.start + 1;
                this.readBuff = new byte[bufferSize];
            }

            @Override
            public void run() {
                try {

                    MappedByteBuffer mapBuffer = rAccessFile.getChannel().map(FileChannel.MapMode.READ_ONLY, start, this.sliceSize);
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    for (int offset = 0; offset < sliceSize; offset += bufferSize) {
                        int readLength;
                        if (offset + bufferSize <= sliceSize) {
                            readLength = bufferSize;
                        } else {
                            readLength = (int) (sliceSize - offset);
                        }
                        mapBuffer.get(readBuff, 0, readLength);
                        for (int i = 0; i < readLength; i++) {
                            byte tmp = readBuff[i];
                            if (tmp == '\n' || tmp == '\r') {
                                handle(bos.toByteArray());
                                bos.reset();
                            } else {
                                bos.write(tmp);
                            }
                        }
                    }
                    if (bos.size() > 0) {
                        handle(bos.toByteArray());
                    }
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }


    }

    class Builder {
        private int threadSize = 1;
        private String charset = null;
        private int bufferSize = 1024 * 1024;
        private IHandle handle;
        private File file;
        private String filePath;

        public Builder(String file, IHandle handle) {
            this.file = new File(file);
            if (!this.file.exists()) {
                throw new IllegalArgumentException("文件不存在!");
            }
            this.handle = handle;
        }


        public Builder withTreahdSize(int size) {
            this.threadSize = size;
            return this;
        }

        public Builder withCharset(String charset) {
            this.charset = charset;
            return this;
        }

        public Builder withBufferSize(int bufferSize) {
            this.bufferSize = bufferSize;
            return this;
        }

        public Builder withFilePath(String filePath) {
            this.filePath = filePath;
            return this;
        }

        public BigFileReader build() {
            return new BigFileReader(this.file, this.handle, this.charset, this.bufferSize, this.threadSize, this.filePath);
        }
    }


}





猜你喜欢

转载自blog.csdn.net/tangthh123/article/details/105855820