一,Synchronization.java文件
/*
@(#)Synchronization.java 8/9/2006
文件同步,可用于文件的备份与更新。
注:本文件使用了开源的jcifs包,用于网络间共享文件的互相访问。
*/
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Properties;
import jcifs.smb.*;
public class Synchronization {
private String addr;
private String user;
private String pass;
private String catalog;
private String confine;
private String general;
private String time;
private File log;
private final byte[] buffer = new byte[2048];
private final SimpleDateFormat style = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public Synchronization() {
init();
}
/**
* 文件同步入口,会首先进行同步目标的检测
*/
public void synchronizator() {
if (catalog != null && !catalog.equals("")) {
File dir = new File(catalog);
if (dir.isDirectory()) {
String[] list = addr.split(";");
if (list != null && list.length > 0) {
for (int i=0; i<list.length; i++)
synchronizate(list[i], catalog, user, pass);
}
} else {
System.out.println("配置文件中的本地同步项不是目录或出现错误。");
}
} else {
System.out.println("本地目录没有配置或移动设备没有准备好。");
}
}
/**
* 根据同步源地址,同步目标,用户名和密码同步网络文件
* @param addr String 同步源地址
* @param target String 同步目标
* @param user String 用户名
* @param pass String 密码
*/
private void synchronizate(String addr, String target, String user, String pass) {
try {
if (addr != null && target != null) {
SmbFile sf = new SmbFile("smb://" + user + ":" + pass + "@" + addr);
File file = new File(target);
if (sf != null && (file.isDirectory())) {
if (!sf.isFile()) {
SmbFile[] list = leach(sf, confine, general);
if (list != null) {
for (int i=0; i<list.length; i++)
synchronizate(list[i], file);
}
} else {
synchronizate(sf, file);
}
}
}
} catch (SmbException e) {
} catch (IOException e) {}
}
/**
* 根据网络文件对象和本地文件对象(目录)同步网络文件
* @param sf SmbFile 网络文件对象
* @param file File 本地文件对象
*/
private void synchronizate(SmbFile sf, File file) {
SmbFileInputStream is = null;
FileOutputStream os = null;
try {
file = new File(file, sf.getName());
if (file.isFile()) {
boolean exists = false;
if (!file.exists()) {
file.createNewFile();
logging("创建"+ file.getName() +"文件成功。");
exists = true;
} else {
if (sf.lastModified() - file.lastModified() > 0)
exists = true;
}
if (exists) {
is = new SmbFileInputStream(sf);
os = new FileOutputStream(file);
int c;
while ((c=is.read(buffer)) != -1)
os.write(buffer, 0, c);
os.flush();
logging("更新"+ file.getName() +"文件成功。");
}
} else {
if (!file.exists()) {
file.mkdir();
logging("创建"+ file.getName() +"目录成功。");
}
SmbFile[] list = leach(sf, confine, general);
if (list != null) {
for (int i=0; i<list.length; i++)
synchronizate(list[i], file);
}
}
} catch (SmbException ex) {
logging("操作"+ file.getName() +"文件出现错误:" + ex.getMessage());
} catch (IOException ex) {
logging("操作"+ file.getName() +"文件出现错误:" + ex.getMessage());
} finally {
try {
if (is != null)
is.close();
} catch (SmbException e) {
} catch (IOException e) {}
try {
if (os != null)
os.close();
} catch (IOException e) {}
}
}
/**
* 根据网络文件对象和同步文件限制后缀名称以及同步限制的方向获取网络文件列表
* @param file SmbFile 网络文件对象
* @param suffix String 同步文件限制后缀名称
* @param direction String 同步限制的方向,指将定义general的值为1时,将反向同步被限制的文件
*/
private SmbFile[] leach(SmbFile file, String suffix, String direction) {
try {
if (suffix == null || suffix.equals(""))
return file.listFiles();
return (direction != null && direction.equals("1"))?
file.listFiles(new SynchronizationSmbFilter(suffix, false)):
file.listFiles(new SynchronizationSmbFilter(suffix, true));
} catch (SmbException ex) {
System.out.println("调用leach(SmbFile f1, String s1, String s2)方法时出现错误:" + ex.getMessage());
}
return null;
}
/**
* 根据操作信息追加操作日志
* @param message String 操作信息
*
*/
private void logging(String message) {
if (log != null) {
time = style.format(Calendar.getInstance().getTime());
try {
if (!log.exists())
log.createNewFile();
FileWriter w = new FileWriter(log, true);
w.write(time + ":" + message + System.getProperty("line.separator"));
w.flush();
w.close();
} catch (IOException e) {}
}
}
/**
* 初始化方法,用于读取属性文件中设定的值项
*/
private void init() {
InputStream is = getClass().getResourceAsStream("config.properties");
Properties pe = new Properties();
try {
pe.load(is);
is.close();
this.addr = pe.getProperty("Server.addr");
this.user = pe.getProperty("Server.user");
this.pass = pe.getProperty("Server.pass");
this.catalog = pe.getProperty("Target.catalog");
this.confine = pe.getProperty("Synchronization.confine");
this.general = pe.getProperty("Synchronization.general");
time = style.format(Calendar.getInstance().getTime());
log = new File("logs", time.substring(0, time.indexOf(" ")) + ".txt");
} catch (IOException ex) {
System.out.println("调用init()方法时出现错误:" + ex.getMessage());
}
}
public static void main(String[] args) {
Synchronization sh = new Synchronization();
sh.synchronizator();
}
class SynchronizationSmbFilter implements jcifs.smb.SmbFileFilter {
private String type;
private boolean direction;
public SynchronizationSmbFilter(String type, boolean accept) {
this.type = type;
this.direction = accept;
}
public boolean accept(SmbFile f) {
try {
if (f.isDirectory())
return true;
} catch (SmbException e) {}
String[] kinds = null;
if (direction) {
if (type == null || type.equals(""))
return false;
String fileName = f.getName();
int i = fileName.lastIndexOf(".");
if (i > 0 && i < fileName.length()-1) {
kinds = type.split(",");
for (int j=0; j<kinds.length; j++) {
if (fileName.substring(i+1).toLowerCase().equals(kinds[j]))
return true;
}
}
} else {
if (type == null || type.equals(""))
return true;
String fileName = f.getName();
int i = fileName.lastIndexOf(".");
if (i > 0 && i < fileName.length()-1) {
kinds = type.split(",");
for (int j=0; j<kinds.length; j++) {
if (fileName.substring(i+1).toLowerCase().equals(kinds[j]))
return false;
}
}
}
return (direction)?false:true;
}
}
}
二,config.properties文件
# Server config
Server.addr = 192.168.0.1/share/;192.168.0.1/公共目录/
Server.user = guest
Server.pass = guest
# target config
Target.catalog = I:/
# Synchronization config
Synchronization.confine =
Synchronization.general =