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

import cn.hutool.core.codec.Base64;
import com.example.demo.exception.SNRepetitiveException;
import com.example.demo.service.SNService;
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.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();

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

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

    @Override
    public void addSN(String SNDto) throws SNRepetitiveException, IOException {
        //加try,catch只为释放锁
        try {
            //加锁
            lock.lock();

            //读取文件,判断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);
            }

            String addSn = SNDto.substring(0,SNDto.indexOf('#'));
            if (set.contains(addSn)) {
                throw new SNRepetitiveException("SN:" + addSn + " 已存在,请勿重复添加");
            }

            //写入
            FileWriter fileWriter = new FileWriter(SNFilePath,true);
            fileWriter.write(SNDto+System.lineSeparator());
            fileWriter.flush();
            fileWriter.close();
        } 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(String SN) throws Exception{
        try {
            lock.lock();

            //读取文件,记录不用删除的数据
            BufferedReader bufferedReader = new BufferedReader(new FileReader(SNFilePath));
            String br;
            StringBuilder stringBuilder = new StringBuilder();
            boolean SNExist = false;
            while ((br=bufferedReader.readLine()) != null) {
                //截取SN
                int index = br.indexOf('#');
                String str = br.substring(0,index == -1? 0 : index);
                if (!SN.equals(str)) {
                    stringBuilder.append(br);
                    stringBuilder.append(System.lineSeparator());
                } else {
                    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();

            }


        } 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();

    }

}