SNServiceImpl.java 6.44 KB
package com.example.demo.service.impl;

import cn.hutool.core.codec.Base64;
import com.example.demo.controller.SNController;
import com.example.demo.dto.AddSNsDTO;
import com.example.demo.dto.DeleteSNsDTO;
import com.example.demo.exception.SNRepetitiveException;
import com.example.demo.service.SNService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class SNServiceImpl implements SNService {
    /**
     *  多线程改写文件存在并发问题,需加锁操作
     */
    private static final Lock lock = new ReentrantLock();

    static Logger logger = LogManager.getLogger(SNServiceImpl.class);

    @Value("${SN.file.path}")
    String SNFilePath;

    @Value("${SN.file.temp.path}")
    String SNTempFilePath;

    @Override
    public void addSN(AddSNsDTO addSNsDTO) throws SNRepetitiveException, IOException {

        //加try,catch只为释放锁
        try {
            //加锁
            lock.lock();
            logger.info("-----------------------------开始添加SNs-----------------------------");
            StringBuilder SNs = new StringBuilder();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String currTime = sdf.format(new Date());
            //读取文件,判断SN是否重复
            Set<String> set = new HashSet<>();
            BufferedReader bufferedReader = new BufferedReader(new FileReader(SNFilePath));
            String br;
            while ((br=bufferedReader.readLine()) != null) {
                //截取SN
                int index = br.indexOf('#');
                String SN = br.substring(0,index == -1? 0 : index);
                set.add(SN);
            }
            for (String SN : addSNsDTO.getSns()) {
                if (set.contains(SN)) {
                    throw new SNRepetitiveException("SN:" + SN + " 已存在,请勿重复添加");
                }
                SNs.append(SN).append("##").append(addSNsDTO.getProjectName()).append("##").append(currTime);
                SNs.append(System.lineSeparator());
            }


            //写入
            FileWriter fileWriter = new FileWriter(SNFilePath,true);
            fileWriter.write(SNs.toString());
            fileWriter.flush();
            fileWriter.close();
            logger.info("-----------------------------结束添加SNs-----------------------------");
        } finally { //释放锁
            lock.unlock();
        }
    }

    @Override
    public String getEncryptSNs() throws IOException {
        File file = new File(SNFilePath);
        //读取文件
        byte[] SNsByteArr = new byte[(int) file.length()];
        FileInputStream fileInputStream = new FileInputStream(file);
        fileInputStream.read(SNsByteArr);
        //加密
        String encodeSNs = Base64.encode(SNsByteArr);

        return encodeSNs;
    }

    @Override
    public void deleteSN(DeleteSNsDTO deleteSNsDTO) throws Exception{
        try {
            lock.lock();
            logger.info("-----------------------------开始删除SNs-----------------------------");

            HashSet<String> deleteSNsSet = new HashSet<>(deleteSNsDTO.getSns());

            //读取文件,记录不用删除的数据
            BufferedReader bufferedReader = new BufferedReader(new FileReader(SNFilePath));
            String br;
            StringBuilder stringBuilder = new StringBuilder();
            StringBuilder existSNs = new StringBuilder();
            //所要删除的SN是否存在
            boolean SNExist = false;
            while ((br=bufferedReader.readLine()) != null) {
                //截取SN
                int index = br.indexOf('#');
                String str = br.substring(0,index == -1? 0 : index);
                if (!deleteSNsSet.contains(str)) {
                    stringBuilder.append(br);
                    stringBuilder.append(System.lineSeparator());
                } else {
                    existSNs.append(str).append("、");
                    SNExist = true;
                }
            }
            bufferedReader.close();

            //如果存在要删除的SN,先将数据备份,再将留存数据覆盖掉原SN文件,避免数据写一半断电丢失。
            if (SNExist) {
                //备份数据
                FileWriter SNTempfileWriter = new FileWriter(SNTempFilePath);
                SNTempfileWriter.write(stringBuilder.toString());
                SNTempfileWriter.flush();
                SNTempfileWriter.close();
                //覆盖掉原来的数据到SN文件中
                FileWriter SNfileWriter = new FileWriter(SNFilePath);
                SNfileWriter.write(stringBuilder.toString());
                SNfileWriter.flush();
                SNfileWriter.close();

            }
            logger.warn("成功删除SNs:{}",existSNs);
            logger.info("-----------------------------结束删除SNs-----------------------------");


        } finally {
            lock.unlock();
        }
    }

    @Override
    public void downloadSNFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
        File file = new File(SNFilePath);

        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-type","application/octet-stream;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(file.getName().trim(), "UTF-8"));
        response.addHeader("Pargam", "no-cache");
        response.addHeader("Cache-Control", "no-cache");

        //读取文件
        byte[] SNsByteArr = new byte[(int) file.length()];
        FileInputStream fileInputStream = new FileInputStream(file);
        fileInputStream.read(SNsByteArr);
        //加密
        String encodeSNs = Base64.encode(SNsByteArr);

        //写入到输出流
        response.addHeader("Content-Length",String.valueOf(encodeSNs.getBytes().length));
        OutputStream outputStream = response.getOutputStream();
        outputStream.write(encodeSNs.getBytes());
        outputStream.flush();
        outputStream.close();

    }

}