2019独角兽企业重金招聘Python工程师标准>>>
package com.ql.ftp;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import ch.ubique.inieditor.IniEditor;
public class Filesysc {
public final static String LOG_FILE_DIR = "f:/ftp/log";
public final static String FILESYSC_FILE_PATH = "f:/ftp/filesync.ini";
public static FileWriter fileWriter = null ;
public static Long currTimestamp = 0L; //时间戳
//获取需要同步的文件,返回false:没有需要同步的文件,true:有文件需要同步
public static boolean getSyncFile(List
String srcdir = iniInfo.get("FILESYNC", "SRCDIR");
String timestamp = iniInfo.get("FILESYNC", "TIMESTAMP");
//本地同步目录
File locDir = new File(srcdir);
//查询需要同步的文件,并存放在lstFile中(记录在filesync.ini文件的时间戳:timestamp)
qryFile(locDir,lstFile,Long.valueOf(timestamp));
int len = lstFile.size();
//日志文件不存在,则创建该日志文件(日志文件:sync_yyyyMMdd.log)
String logFile = getLogFile(LOG_FILE_DIR);
fileWriter = new FileWriter(logFile, true);
fileWriter.write("\n\n"+dateFormat(new Date(),"yyyy-MM-yy HH:mm:ss")+"----> 文件同步开始......");
if(len == 0){
fileWriter.write("\n"+dateFormat(new Date(),"yyyy-MM-yy HH:mm:ss")+"----> 没有需要同步的文件!");
fileWriter.close();
return false;
}else{
fileWriter.write("\n"+dateFormat(new Date(),"yyyy-MM-yy HH:mm:ss")+"----> 文件扫描完成,需要同步文件 "+len+" 个,同步开始");
}
//对存放在lstFile中的文件按修改时间排序
File file = null;
for(int i=0;i
file = lstFile.get(j);
lstFile.set(j, lstFile.get(j+1)) ;
lstFile.set(j+1, file) ;
}
}
}
System.out.println("***************************************");
for(File f:lstFile){
System.out.println(f.getAbsolutePath());
}
System.out.println("***************************************");
return true ;
}
public static void main(String[] args) throws IOException {
//读取filesync.ini文件配置
IniEditor iniInfo = getIniInfo(FILESYSC_FILE_PATH);
List
//获取排好的需要同步的文件lstFile
boolean b = getSyncFile(lstFile,iniInfo);
if(!b)
return ;
boolean res = false ;
//同步本地文件到FTP服务器
res = syncFiles(lstFile,iniInfo);
//同步成功时,才保存时间戳,否则不保存时间戳
if(res){
iniInfo.set("FILESYNC", "TIMESTAMP",String.valueOf(currTimestamp));
iniInfo.save(new File(FILESYSC_FILE_PATH));
}
}
public static boolean syncFiles(List
String srcdir = iniInfo.get("FILESYNC", "SRCDIR");
String server = iniInfo.get("FILESYNC", "SERVER");
String port = iniInfo.get("FILESYNC", "PORT");
String user = iniInfo.get("FILESYNC", "USER");
String password = iniInfo.get("FILESYNC", "PASSWORD");
if(fileWriter == null){
String logFile = getLogFile(LOG_FILE_DIR);
fileWriter = new FileWriter(logFile, true);
}
//写日志文件
//时间戳
currTimestamp = Long.valueOf(dateFormat(new Date(),"yyyyMMddHHmmss"));
fileWriter.write("\n"+dateFormat(new Date(),"yyyy-MM-yy HH:mm:ss")+"----> 开始同步文件,时间戳为:"+currTimestamp);
//本地目录的字符数
int n = srcdir.length();
//同步List
List
FTPClient ftpClient = new FTPClient();
//登陆FTP
boolean b_login = loginFtp(ftpClient,server,Integer.valueOf(port),user,password,fileWriter);
if(!b_login){
fileWriter.write("\n"+dateFormat(new Date(),"yyyy-MM-yy HH:mm:ss")+"----> 登陆FTP失败......");
if(fileWriter != null)
fileWriter.close();
return false ;
}
// 设置被动模式
ftpClient.enterLocalPassiveMode();
// 设置以二进制方式传输,不能设置此选项
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
//下面三行代码必须要,而且不能改变编码格式
ftpClient.setControlEncoding("GBK");
FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
conf.setServerLanguageCode("zh");
boolean b = false ;
//循环上传需要同步的文件到FTP服务器上
for(File f:syncList){
synchronized(Filesysc.class){
f.getParentFile().getPath();
String path = f.getParentFile().getPath().substring(n-1);
InputStream input=new FileInputStream(f);
path = new String(path.getBytes("GBK"),"ISO8859-1");
String filename = new String(f.getName().getBytes("GBK"),"ISO8859-1");
b = uploadFile(ftpClient, path,filename,input,fileWriter);
if(!b){
try {
Thread.sleep(1000);
for(int i=1;i<=10;i++){
input=new FileInputStream(f);
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~ ---> path="+new String(path.getBytes("ISO8859-1"),"GBK"));
b = uploadFile(ftpClient, path,filename,input,fileWriter);
System.err.println("~~~~~~~~~~~~~~~~~~~~ --->"+i+" "+new String(filename.getBytes("ISO8859-1"),"GBK")+"--->"+(b)+"~~~~~~~~~~~~~~~~~~");
if(b){
fileWriter.write("\n"+dateFormat(new Date(),"yyyy-MM-yy HH:mm:ss")
+"----> 文件["+new String(filename.getBytes("ISO8859-1"),"GBK")+"]同步成功!");
break;
}else{
fileWriter.write("\n"+dateFormat(new Date(),"yyyy-MM-yy HH:mm:ss")
+"----> 文件["+new String(filename.getBytes("ISO8859-1"),"GBK")
+"]同步失败,错误原因:上传该文件时出现异常!");
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
//最终还是有文件不能成功 上传,则退出程序
if(!b)
break;
}else{
input.close();
}
}
}
ftpClient.logout();
ftpClient.disconnect();
if(b)
fileWriter.write("\n"+dateFormat(new Date(),"yyyy-MM-yy HH:mm:ss")+"---->文件同步完成,共同步文件"+lstFile.size()+" 个");
else
fileWriter.write("\n"+dateFormat(new Date(),"yyyy-MM-yy HH:mm:ss")+"---->文件同步失败......");
if(fileWriter != null)
fileWriter.close();
return b ;
}
//加载filesysc.ini文件
public static IniEditor getIniInfo(String fileName){
File file = new File(fileName);
IniEditor ini = new IniEditor();
try {
ini.load(file);
} catch (IOException e) {
System.out.println("获取filesysc.ini文件信息时,出现异常");
e.printStackTrace();
}
return ini ;
}
//登陆FTP
public static boolean loginFtp(FTPClient ftpClient,String server,int port,String user,String password,FileWriter fileWriter){
boolean b = false ;
try {
ftpClient.connect(server, port);
b = ftpClient.login(user, password);
} catch (Exception e) {
try {
fileWriter.write("\n"+dateFormat(new Date(),"yyyy-MM-yy HH:mm:ss")+"---->"+e.getMessage());
} catch (IOException e1) {
e1.printStackTrace();
}
}
return b;
}
//得到日志文件绝对路径,不存在则创建
public static String getLogFile(String path) throws IOException{
File dir = new File(path);
if(!dir.exists()){
dir.mkdirs();
}
String logFile = path+"/sync_"+dateFormat(new Date(),"yyyyMMdd")+".log";
File file = new File(logFile);
if(!file.exists()){
file.createNewFile();
}
return logFile;
}
//格式化时间
public static String dateFormat(Date date,String format){
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
}
//查询目录中大于时间戳的所有文件
public static void qryFile(File file,List
if(file.isFile()&& timestamp < Long.valueOf(dateFormat(new Date(file.lastModified()),"yyyyMMddHHmmss"))){
System.err.println("递归文件------------->"+file.getPath());
lstFile.add(file);
}else{
System.err.println("递归文件夹-------------->"+file.getPath());
File[] files = file.listFiles();
for(File f:files){
if(f.isFile() && timestamp < Long.valueOf(dateFormat(new Date(f.lastModified()),"yyyyMMddHHmmss"))){
lstFile.add(f);
System.out.println("递归文件-------------->"+f.getPath());
}else if(f.isDirectory()){
qryFile(f,lstFile,timestamp);
}
}
}
}
/**
* Description: 向FTP服务器 单个上传文件
* @param path FTP服务器保存目录
* @param filename 上传到FTP服务器上的文件名
* @param input 输入流
* @return 成功返回true,否则返回false
* @throws IOException
*/
public static boolean uploadFile(FTPClient ftpClient, String path, String filename, InputStream input, FileWriter writer ) {
boolean success = false;
String pth = path ;
try {
//切换到默认目录
ftpClient.changeWorkingDirectory("");
//切换FTP服务器存放文件的目录
if(!"".equals(pth)){
pth = pth.replace("\\", "/");
String[] arr= pth.split("/");
for(String p:arr){
p = p.trim();
if(!"".equals(p)){
if(!ftpClient.changeWorkingDirectory(p)){
ftpClient.makeDirectory(p);
}
//切换FTP目录
ftpClient.changeWorkingDirectory(p);
}
}
}
ftpClient.enterLocalPassiveMode();
//删除该目录上的同名文件
ftpClient.deleteFile(filename);
System.out.println("---------------------> uploadFile filename="+new String(filename.getBytes("ISO8859-1"),"GBK"));
success = ftpClient.storeFile(filename, input);
if(input != null)
input.close();
} catch (IOException e) {
try {
if(input != null)
input.close();
System.err.println("上传"+new String(filename.getBytes("ISO8859-1"),"GBK")+" 失败......");
if(input != null)
input.close();
} catch (UnsupportedEncodingException e3) {
e3.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
return success;
}
}
filesync.ini文件格式:
[filesync]
srcdir = F:/qianlong/
server = 192.168.3.101
port = 21
user = anonymous
password =
timestamp = 20120914144202
注:可以同步中文目录及中文名称文件,当文件比较大时,容易同步失败。代码简单、易懂。参考了网上一些代码。
【使用 commons-net-2.2.jar、inieditor-r2.jar】