whyclj
2019-07-26 5d739fbf09719fc4e7f86b3ced0ee174c27a5de7
DataBase_Bakeup_SocketServer/src/com/main/HzipServer.java
@@ -8,19 +8,31 @@
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class HzipServer extends Thread {
   Socket socket;
   public static final String MYSQLBACKUPDIR = "MySqlBackUpDir";         //mysql数据库备份文件夹名称
   public static final int MAXSTORAGE = 3;
   public static boolean ISNEEDDELETE = false;
   public Socket socket;
   
   public HzipServer() {
      // TODO Auto-generated constructor stub
   }
   
   public HzipServer(Socket socket) {
      this.socket = socket;
   }
   public DeleteRegularThread createDeleteRegularThreadStructure() {
      return new DeleteRegularThread();
   }
   
   @Override
@@ -29,14 +41,14 @@
         InputStream ins = socket.getInputStream();
         ZipInputStream zis=new ZipInputStream(ins);
         
         String rootDir=null;
         //在此次连接中,是否是第一次读到ZipEntry。读到的第一个Entry,就是正在被传输的文件夹。
         String rootDir="REGULAR_BACKUP";
         //在此次连接中,是否是第一次读到ZipEntry.读到的第一个Entry,就是正在被传输的文件夹。
         boolean isFirst=true;
         String savePath="D:"+File.separator+"gitspace"+File.separator;
         String savePath="D:"+File.separator+MYSQLBACKUPDIR+File.separator;
         //以上为保存接收到的文件夹的位置。
         //如,服务端传输的文件夹是D:\zipfolder,则该文件夹在客户端将保存在D:\gitspace\。
         //为了良好的移植性,这里用File.separator,
         //因为分隔符在不同的操作系统上,可能不一样。
         //如,服务端传输的文件夹是D:\zipfolder,则该文件夹在客户端将保存在D:\MYSQLBACKUPDIR\。
         //为了良好的移植性,这里用File.separator,
         //因为分隔符在不同的操作系统上,可能不一样。
         
         ZipEntry ze=null;
         ZipOutputStream zos=null;
@@ -47,6 +59,7 @@
         while( (ze=zis.getNextEntry())!=null  )
         {
            String name=ze.getName();
            System.out.println(name);
            File file=null;
            if(ze.isDirectory())
            {
@@ -84,7 +97,12 @@
            }
            else
            {
               int index=name.indexOf(rootDir);
               int index;
               if(isFirst) {
                  index = name.lastIndexOf("\\");
               }else {
                  index=name.indexOf(rootDir);
               }
               String tempFileDir=name.substring(index,name.length());
               file=new File(savePath+tempFileDir);
               fos=new FileOutputStream(file);
@@ -98,22 +116,131 @@
            }
         }
         socket.close();
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         System.out.println("Backup MySql OK at " + sdf.format(new Date()));
         ISNEEDDELETE = true;
      } catch (UnknownHostException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
      } finally {
         if(socket != null) {
            try {
               socket.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
      }
   
   }
   /**
    *    定期删除多余的备份数据
    * @author LiJun
    *
    */
   class DeleteRegularThread extends Thread{
      @Override
      public void run() {
         while(true) {
            try {
               String savePath="D:"+File.separator+MYSQLBACKUPDIR+File.separator;
               File fileroot = new File(savePath);
               File[] files = fileroot.listFiles();
               if(ISNEEDDELETE && fileroot.exists() && files.length >3) {
                  deleteFileRoot(savePath, MAXSTORAGE);      //删除超过3次的备份数据
                  ISNEEDDELETE = false;
               }
               sleep(1000);
            } catch (Exception e) {
               e.printStackTrace();
            }
         }
      }
      /**
        *    递归删除目录下的所有文件及子目录下所有文件
        * @param dir 将要删除的文件目录
        * @return boolean Returns "true" if all deletions were successful.
        *                 If a deletion fails, the method stops attempting to
        *                 delete and returns "false".
        */
       public boolean deleteDir(File dir) {
           if (dir.isDirectory()) {
               String[] children = dir.list();
               //递归删除目录中的子目录下
               for (int i=0; i<children.length; i++) {
                   boolean success = deleteDir(new File(dir, children[i]));
                   if (!success) {
                       return false;
                   }
               }
           }
           // 目录此时为空,可以删除
           return dir.delete();
       }
       /**
       * 保留当前目录中的指定数目的文件夹         (删除当前文件夹下的最早之前的备份数据)
       * @param filePath            需要备份数据的文件夹
       * @param filecount             备份数据的笔数
       */
      public void deleteFileRoot(String filePath,int filecount) {
         File file = new File(filePath);
         if(file.exists()) {
            File[] files = file.listFiles();
            Arrays.sort(files, new CompratorByLastModified());
            if(files.length>filecount && filecount>0) {
               //System.out.println("文件夹个数:"+files.length + "\t 最大笔数:"+filecount);
               for(int i=filecount;i<files.length;i++) {
                  deleteDir(files[i]);
               }
            }
         }
      }
   }
   //比较两个文件夹下的文件
   static class CompratorByLastModified implements Comparator<File> {
      public int compare(File f1, File f2) {
         long diff = f1.lastModified() - f2.lastModified();
         if (diff > 0) {
            return -1;//倒序正序控制
         }else if (diff == 0) {
            return 0;
         }else {
            return 1;//倒序正序控制
         }
      }
   }
   
   public static void main(String[] args) {
      try {
         ServerSocket serveracept = new ServerSocket(10100);
         HzipServer server = null;
         server = new HzipServer();
         DeleteRegularThread deletethread = server.createDeleteRegularThreadStructure();
         deletethread.start();      //启动删除多余备份数据库线程
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         System.out.println("MySql BackUpThread Start at "+sdf.format(new Date()));
         while(true) {
            Socket s = serveracept.accept();
            System.out.println("监听到客户端连接");
            new HzipServer(s).start();
            try {
               Socket s = serveracept.accept();
               //System.out.println("监听到客户端连接");
               server = new HzipServer(s);
               server.start();
            } catch (Exception e) {
               e.printStackTrace();
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }