以文件最后更新时间为依据,同步两个文件夹下的所有文件

来源:互联网 发布:文玩市场淘宝三人行 编辑:程序博客网 时间:2024/05/23 00:04

package free;

import javax.swing.*;
import javax.swing.border.TitledBorder;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.ArrayList;
import java.util.LinkedList;
public class MainFrame extends JFrame {
 private final int WIDTH=600;
 private final int HEIGHT=400;
 
 protected JButton b1;
 protected JButton b2;
 protected JButton syn;
 protected JTextField jtf1;
 protected JTextField jtf2;
 protected JTextArea area;
 protected JMenuBar mbar;
 
 private java.util.List<File> from=new LinkedList<File>();
 private java.util.List<File> to=new LinkedList<File>();
 public MainFrame(){
  this.setSize(WIDTH, HEIGHT);
  
  /*创建菜单
   * */
  mbar=new JMenuBar();
  this.setJMenuBar(mbar);
  this.setTitle("DirSyn");
  JMenu menu=new JMenu("File");
  JMenuItem jmi1=new JMenuItem("Open source");
  JMenuItem jmi2=new JMenuItem("Open destination");
  JMenuItem jmi3=new JMenuItem("Exit");
  
  menu.add(jmi1);
  menu.add(jmi2);
  menu.addSeparator();
  menu.add(jmi3);
  mbar.add(menu);
  /*初始化其他控件,并添加监听器
   * */
  b1=new JButton("Open source");
  b2=new JButton("Open destination");
  syn=new JButton("Synchronize");
  jtf1=new JTextField(20);
  jtf2=new JTextField(20);
  //将 area 封装在滚动条内
  area =new JTextArea(10,40);  
  JScrollPane sbar=new JScrollPane();
  sbar.setViewportView(area);
  sbar.setAutoscrolls(true);
  sbar.setEnabled(true);
  //设置布局
  JPanel bottom = new JPanel();
  GridBagLayout gridBagLayout = new GridBagLayout();
  GridBagConstraints c = new GridBagConstraints();
  c.fill=GridBagConstraints.HORIZONTAL;
  bottom.setLayout(gridBagLayout);
  //bottom.setBackground(Color.GRAY);
  bottom.setAlignmentX(LEFT_ALIGNMENT);
  bottom.setAlignmentY(TOP_ALIGNMENT);
  gridBagLayout.setConstraints(b1, c);
  bottom.add(b1);
  c.gridwidth=GridBagConstraints.REMAINDER;  
  gridBagLayout.setConstraints(jtf1, c);
  bottom.add(jtf1);
  
  c.gridwidth=1;
  c.gridy=1;
  gridBagLayout.setConstraints(b2, c);
  bottom.add(b2);
  gridBagLayout.setConstraints(jtf2, c);
  bottom.add(jtf2);
  
  c.gridy=2;
  gridBagLayout.setConstraints(syn, c);
  bottom.add(syn);
  
  c.gridy=3;
  c.gridwidth=GridBagConstraints.REMAINDER;
  c.gridheight=4;
  JPanel dt=new JPanel();
  dt.setBorder(new TitledBorder("Detail"));
  dt.add(sbar);
  gridBagLayout.setConstraints(dt, c);
  bottom.add(dt);
  
  getContentPane().setLayout(new FlowLayout(FlowLayout.LEFT));
  getContentPane().add(bottom);
  //设置监听器
  b1.addActionListener(new addFileListener());
  b2.addActionListener(new addFileListener());
  syn.addActionListener(new addFileListener());
  
  /*设置窗体位置*/
  this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  Dimension d=Toolkit.getDefaultToolkit().getScreenSize();
  this.setLocation(((int)d.getWidth()-WIDTH)/2 ,((int)d.getHeight()-HEIGHT)/2 );
  this.setVisible(true);
 }
 class addFileListener implements ActionListener{

  @Override
  public void actionPerformed(ActionEvent arg0) {
   if(arg0.getActionCommand().equals("Open source")){
    System.out.println("source clicked");
    JFileChooser jfc=new JFileChooser();
    jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    jfc.showOpenDialog(MainFrame.this);
    File file=jfc.getSelectedFile();
    if(file==null)return;
    jtf1.setText(file.getAbsolutePath());
    //将选择文件下的 所有文件 压入 堆栈
    pushFile(file,from);
   }else if(arg0.getActionCommand().equals("Open destination")){
    System.out.println("destination clicked");
    JFileChooser jfc=new JFileChooser();
    jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    jfc.showOpenDialog(MainFrame.this);
    File file=jfc.getSelectedFile();
    if(file==null)return;
    jtf2.setText(file.getAbsolutePath());
    //将选择文件下的 所有文件 压入 堆栈
    pushFile(file,to);
   }else if(arg0.getActionCommand().equals("Synchronize")){
    System.out.println("synchronized clicked");
    if(jtf1.getText()==null || jtf2.getText()==null ||jtf1.getText().trim().length()<=0||jtf2.getText().trim().length()<=0){
     JOptionPane.showMessageDialog(MainFrame.this, "请选择两个需要同步的文件夹");
     return ;
    }
    if(synDir(from ,to)){
     JOptionPane.showMessageDialog(MainFrame.this, "同步成功", null,JOptionPane.INFORMATION_MESSAGE);
    }else{
     JOptionPane.showMessageDialog(MainFrame.this, "同步失败", null, ERROR);
    }
   }
   
  }
  //将 已选文件夹中 所有类型 文件 压入 对应 堆栈,等待 同步处理
  public void pushFile(File dir,java.util.List<File> ls){
   if(dir==null)return;
   String dirPath=dir.getAbsolutePath();
   String[] fn=dir.list();
   for(String f:fn){
    File fi=new File(dirPath+"/"+f);
    if(fi.isFile()){
     ls.add(fi);
     System.out.println(fi.getAbsolutePath());
    }else{
     pushFile(fi,ls);
    }    
   }
  }
  //同步时,以源文件夹 为据,依次同步最新文件。同步完成后,目的文件夹中剩余的 文件将复制到源文件夹
  public boolean synDir(java.util.List<File> dfrom,java.util.List<File> dto){
   if(dfrom.size()<=0 && dto.size()<=0){
    JOptionPane.showMessageDialog(MainFrame.this, "需要同步的两个文件夹都是空的");
    return false;
   }
   for(File f:from){
    String str=f.getAbsolutePath().replace(jtf1.getText().trim(), jtf2.getText().trim());
    //组建一个临时文件(用目标文件夹路径 替换 源文件夹路径),便于从目标文件中 查找与此一致的文件
    File tempFile =new File(str);
    //No1.如果存在源文件夹中的 文件  也存在目标文件夹,
    if(dto.contains(tempFile) ){
     synFile(f, dto.get(dto.indexOf(tempFile)));
     //同步完后 ,从目标文件夹 堆栈 删除 改文件
     dto.remove(tempFile);
    }else{ //No2.否则,文件存在源文件夹,不存在于目标文件夹
     String str2=f.getAbsolutePath().replace(jtf1.getText().trim(), jtf2.getText().trim());
     synFile(f,new File(str2));
    }
   }
   //No3.存在于目标文件夹,但是不存在于源文件夹
   if(dto.size()>0){
    for(File f:dto){
     String str=f.getAbsolutePath().replace(jtf2.getText().trim(), jtf1.getText().trim());
     synFile(f,new File(str));
    }
   }
   return true;
  }
  //根据文件 最后依次修改时间,确定最新文件,然后同步
  public void synFile(File dfile,File tfile){
   if(dfile.lastModified()>tfile.lastModified()){
    area.append("Synchronized from "+dfile.getAbsolutePath()+" to " +tfile.getAbsolutePath()+"/n");
    copyFile(dfile,tfile);
   }else if(dfile.lastModified()<tfile.lastModified()){
    area.append("Synchronized from "+tfile.getAbsolutePath()+" to " +dfile.getAbsolutePath()+"/n");
    copyFile(tfile,dfile);
   }
  }
  //复制文件
  public boolean copyFile(File fromf,File tof){
   FileInputStream in=null;
   FileOutputStream out=null;
   byte[]buffer=new byte[4*1024];   
   try {
    //如果目标文件不存在
    if(!tof.exists()){
     //创建路径
     File d=tof.getParentFile();
     d.mkdirs();
     //创建文件
     boolean r=tof.createNewFile();
     area.append("New file "+tof.getAbsolutePath()+"/n");    
    }
    in=new FileInputStream(fromf);
    out=new FileOutputStream(tof);
    while( (in.read(buffer) )>0 ){
     out.write(buffer);
    }
    out.flush();
   } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   try {
    if(in!=null)in.close();
    if(out!=null)out.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   return true;
  }
 }
}

原创粉丝点击