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