ftputil class
package com;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Created by xiao on 2018/1/21.
*/
public class FTPUtil {
public FTPClient ftp;
public ArrayList<String> arFiles;
public Map map;
private OutputStream os = null;
private InputStream is = null;
private static Logger logger = LoggerFactory.getLogger(FTPUtil.class);
private static String ftpIp = "192.111.222.333";// PropertiesUtil.getProperty("ftp.server.ip")
private static String ftpUser = "ftpadmin";// PropertiesUtil.getProperty("ftp.user")
private static String ftpPass = "ftpadmin";// PropertiesUtil.getProperty("ftp.pass")
FTPUtil(String ip, int port, String user, String pwd) {
this.ip = ip;
this.port = port;
this.pwd = pwd;
}
public FTPUtil() {
ftp = new FTPClient();
arFiles = new ArrayList<String>();
map = new HashMap<String, Long>();
}
/**
* 对外暴露的上传文件方法
*
* @param fileList
* @return
*/
public static boolean uploadFile(List<File> fileList) throws IOException {
FTPUtil ftpUtil = new FTPUtil(ftpIp, 21, ftpUser, ftpPass);
logger.info("开始连接FTP服务器");
// 把异常抛给service层,不在此处理
boolean result = ftpUtil.uploadFile("img", fileList);
logger.info("开始连接FTP服务器,结束上传,上传结果{}", result);
return result;
}
private boolean uploadFile(String remotePath, List<File> fileList) throws IOException {
boolean uploaded = true;
FileInputStream fis = null;
// 连接FTP服务器
if (connectServer(this.getIp(), this.getUser(), this.getPwd())) {
try {
ftpClient.changeWorkingDirectory(remotePath);
ftpClient.setBufferSize(1024);
ftpClient.setControlEncoding("UTF-8");
// 设置成二进制格式可以防止乱码
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// 被动模式存储
ftpClient.enterLocalPassiveMode();
// 遍历文件存储
for (File fileItem : fileList) {
// 把文件转成文件流
fis = new FileInputStream(fileItem);
// 调用storeFile方法存储
ftpClient.storeFile(fileItem.getName(), fis);
}
} catch (IOException e) {
logger.error("上传文件异常", e);
uploaded = false;
} finally {
// 关闭连接和文件流
fis.close();
ftpClient.disconnect();
}
}
return uploaded;
}
/**
* 连接FTP服务器
*
* @param ip
* @param user
* @param pwd
* @return
*/
public boolean connectServer(String ip, String user, String pwd) {
boolean isSuccess = false;
ftpClient = new FTPClient();
try {
ftpClient.connect(ip);
isSuccess = ftpClient.login(user, pwd);
} catch (IOException e) {
logger.error("FTP服务器连接失败", e);
}
return isSuccess;
}
/**
* 登陆FTP服务器
*
* @param host
* FTPServer IP地址
* @param port
* FTPServer 端口
* @param username
* FTPServer 登陆用户名
* @param password
* FTPServer 登陆密码
* @return 是否登录成功
* @throws IOException
*/
public boolean login(String host, int port, String username, String password) throws IOException {
this.ftp.connect(host, port);
if (FTPReply.isPositiveCompletion(this.ftp.getReplyCode())) {
if (this.ftp.login(username, password)) {
/**
* 需要注意这句代码,如果调用List()方法出现,文件的无线递归,与真实目录结构不一致的时候,可能就是因为转码后,
* 读出来的文件夹与正式文件夹字符编码不一致所导致。
* 则需去掉转码,尽管递归是出现乱码,但读出的文件就是真实的文件,不会死掉。等读完之后再根据情况进行转码。
* 如果ftp部署在windows下,则: for (String arFile : f.arFiles) { arFile
* = new String(arFile.getBytes("iso-8859-1"), "GBK");
* logger.info(arFile); }
*/
this.ftp.setControlEncoding("GBK");
return true;
}
}
if (this.ftp.isConnected()) {
this.ftp.disconnect();
}
return false;
}
/**
* 递归遍历出目录下面所有文件
*
* @param pathName
* 需要遍历的目录,必须以"/"开始和结束
* @throws IOException
*/
public void List(String pathName) throws IOException {
if (pathName.startsWith("/") && pathName.endsWith("/")) {
// 更换目录到当前目录
this.ftp.changeWorkingDirectory(pathName);
FTPFile[] files = this.ftp.listFiles();
for (FTPFile file : files) {
if (file.isFile()) {
arFiles.add(pathName + file.getName());
} else if (file.isDirectory()) {
// 需要加此判断。否则,ftp默认将‘项目文件所在目录之下的目录(./)’与‘项目文件所在目录向上一级目录下的目录(../)’都纳入递归,这样下去就陷入一个死循环了。需将其过滤掉。
if (!".".equals(file.getName()) && !"..".equals(file.getName())) {
List(pathName + file.getName() + "/");
}
}
}
}
}
/**
* 递归遍历目录下面指定的文件名
*
* @param pathName
* 需要遍历的目录,必须以"/"开始和结束
* @param ext
* 文件的扩展名
* @throws IOException
*/
public Map List(String pathName, String ext) throws IOException {
long size=0;
if (pathName.startsWith("/") && pathName.endsWith("/")) {
// 更换目录到当前目录
this.ftp.changeWorkingDirectory(pathName);
FTPFile[] files = this.ftp.listFiles();
for (FTPFile file : files) {
if (file.isFile()) {
String name1=file.getName();
if (file.getName().endsWith(ext)) {
map.put(name1.substring(0,file.getName().indexOf(".")),
file.getSize());
arFiles.add(pathName + file.getName());
}
size++;
} else if (file.isDirectory()) {
if (!".".equals(file.getName()) && !"..".equals(file.getName())) {
List(pathName + file.getName() + "/", ext);
}
}
}
// map.put("size", size);
}
return map;
}
public long getCompressFileOrgin(String remotePath,String fileName) throws IOException{
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(remotePath+"/"+fileName));
ZipEntry zipEntry;
long compd=0;
while ( (zipEntry = zipIn.getNextEntry()) != null ) {
zipIn.closeEntry();
if (!zipEntry.isDirectory()) {
String name = zipEntry.getName();
long size = zipEntry.getSize();
compd = zipEntry.getCompressedSize();
System.out.printf("%s , size=%d, compressed size=%d\r\n", name, size, compd);
}
}
zipIn.close();
return compd;
}
public void downloadFiles(String ftpFileName, String downloadDate) {
downloadFileByDate(ftpFileName, downloadDate);
}
/**
* 下载指定文件
* @param ftpFileName
* @param downloadDate
*/
private void downloadFileByDate(String ftpFileName,String downloadDate){
try {
if(isDir(ftpFileName)){//文件夹
String[] names = ftpClient.listNames();
for(int i=0;i<names.length;i++){
System.out.println(names[i] + "--------------");
// if(pattern.matcher(names[i]).matches()){//如果是8位数字的文件夹
downloadFileByDate(ftpFileName + "/" + downloadDate,downloadDate); //指定文件夹
ftpClient.changeToParentDirectory();
// }
if(isDir(names[i])){
downloadFileByDate(ftpFileName + "/" + names[i],downloadDate);
ftpClient.changeToParentDirectory();
}else{
is = ftpClient.retrieveFileStream(names[i]);//取出文件转成输入流
//在retrieveFileStream后面加上completePendingCommand,changeWorkingDirectory才能正常输出
//而且completePendingCommand一定要在is.close()之后,否则容易程序死掉,坑爹啊
ftpClient.completePendingCommand();
//ftpClient.changeToParentDirectory();
}
测试
//if("04".equals(names[i])){
//break;
//}
}
} else {//文件
is = ftpClient.retrieveFileStream(ftpFileName);
ftpClient.completePendingCommand();
ftpClient.changeToParentDirectory();
}
logger.info("下载成功!");
}catch (Exception e) {
// TODO: handle exception
}
}
private boolean success=false;
public boolean downloadFile(String remotePath,String fileName,String localPath,String ext) throws Exception{
boolean chg=ftp.changeWorkingDirectory(new String(remotePath.getBytes("GBK"),"ISO-8859-1"));//转移到FTP服务器目录
// log.error("remote path:" + ftp.printWorkingDirectory());
System.out.println("changeWorkingDirectory:"+chg);
if(chg){
FTPFile[] fs = ftp.listFiles();
System.out.println("files...."+fs.length);
// log.error("files...."+fs.length);
for(FTPFile ff:fs){
if(ff.getName().equals(fileName+ext)){
File localFile = new File(localPath+"/"+ff.getName());
OutputStream is = new FileOutputStream(localFile);
ftp.retrieveFile(ff.getName(), is);
is.close();
}
}
success = true;
}else{
success = false;
}
// ftp.logout();
return success;
}
/**
* @param ftpFileName
*/
public void downloadFileOrDir(String ftpFileName){
try {
if(isDir(ftpFileName)){//文件夹
String[] names = ftpClient.listNames();
for(int i=0;i<names.length;i++){
System.out.println(names[i] + "--------------");
if(isDir(names[i])){
downloadFileOrDir(ftpFileName + "/" + names[i]);
ftpClient.changeToParentDirectory();
}else{
File loadFile = new File(ftpFileName + File.separator
+ names[i]);
os = new FileOutputStream(loadFile);
ftpClient.retrieveFile(names[i], os);
}
}
} else {//文件
File file = new File(ftpFileName);
os = new FileOutputStream(file);
ftpClient.retrieveFile(file.getName(), os);
ftpClient.changeToParentDirectory();
}
logger.info("下载成功!");
} catch(Exception e){
}
}
public void closeFtp() throws IOException{
if(ftp!=null)
ftp.logout();
}
/** * 删除文件 *
* @param pathname FTP服务器保存目录 *
* @param filename 要删除的文件名称 *
* @return */
public boolean deleteFile(String pathname, String filename){
boolean flag = false;
try {
System.out.println("开始删除文件");
//还在登录
// initFtpClient();
//切换FTP目录
ftpClient.changeWorkingDirectory(pathname);
ftpClient.dele(filename);
ftpClient.logout();
flag = true;
System.out.println("删除文件成功");
} catch (Exception e) {
System.out.println("删除文件失败");
e.printStackTrace();
} finally {
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
}
return flag;
}
// 复制文件
public static void copyFile(File sourceFile, File targetFile)
throws IOException {
BufferedInputStream inBuff = null;
BufferedOutputStream outBuff = null;
try {
inBuff = new BufferedInputStream(new FileInputStream(sourceFile));
outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));
byte[] b = new byte[1024 * 5];
int len;
while ((len = inBuff.read(b)) != -1) {
outBuff.write(b, 0, len);
}
outBuff.flush();
} finally {
if (inBuff != null)
inBuff.close();
if (outBuff != null)
outBuff.close();
}
}
// 复制文件夹
public static void copyDirectiory(String sourceDir, String targetDir)
throws IOException {
(new File(targetDir)).mkdirs();
File[] file = (new File(sourceDir)).listFiles();
for (int i = 0; i < file.length; i++) {
if (file[i].isFile()) {
File sourceFile = file[i];
File targetFile = new File(
new File(targetDir).getAbsolutePath() + File.separator
+ file[i].getName());
copyFile(sourceFile, targetFile);// 递归调用
}
if (file[i].isDirectory()) {
String dir1 = sourceDir + "/" + file[i].getName();
String dir2 = targetDir + "/" + file[i].getName();
copyDirectiory(dir1, dir2);
}
}
}
/**
* * 判断是否是目录 * @param fileName * @return
*/
public boolean isDir(String fileName) {
try {
// 切换目录,若当前是目录则返回true,否则返回true。
boolean falg = ftpClient.changeWorkingDirectory(fileName);
return falg;
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return false;
}
//方法功能:递归将file中文件都添加到集合中
public static void getDataFiles(File file,ArrayList<File> list){
if(file.isFile()){//如果file是文件
list.add(file);
}else{//如果file是文件夹
File[] listFiles = file.listFiles();//获取file中每一个文件,并遍历递归
for (File file2 : listFiles) {
getDataFiles( file2,list);
}
}
}
private String ip;
private int port;
private String user;
private String pwd;
private FTPClient ftpClient;
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public static String getFtpTp() {
return ftpIp;
}
public static void setFtpTp(String ftpTp) {
FTPUtil.ftpIp = ftpTp;
}
public static String getFtpUser() {
return ftpUser;
}
public static void setFtpUser(String ftpUser) {
FTPUtil.ftpUser = ftpUser;
}
public static String getFtpPass() {
return ftpPass;
}
public static void setFtpPass(String ftpPass) {
FTPUtil.ftpPass = ftpPass;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public FTPClient getFtpClient() {
return ftpClient;
}
public void setFtpClient(FTPClient ftpClient) {
this.ftpClient = ftpClient;
}
}
FtpTest class
package hello;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import com.FTPUtil;
import com.google.common.collect.Lists;
public class FtpTest {
static Logger logger = LoggerFactory.getLogger(FtpTest.class);
public static void main(String[] args) throws Exception {
//日志记录
Map<String,Long> map =null;
FTPUtil fTPUtil=new FTPUtil();
boolean connetFlag = fTPUtil.login("192.168.182.145",21,"ftpadmin","ftpadmin");
if(connetFlag){
map = fTPUtil.List("/usr/ftp/file/",".zip");
}else{
return;
}
for(Map.Entry<String,Long> it : map.entrySet()){
System.out.println("key="+it.getKey()+"value="+it.getValue());
}
File file = new File("");
String filePath = file.getCanonicalPath()+"\\path";
String bakPath=file.getCanonicalPath()+"\\bak";
File fileDir = new File(filePath);
File bakDir=new File(bakPath);
//判断文件是否存在,不存在就创建一个新的
if(!fileDir.exists()){
//使文件可以改,因为Tomcat发布服务后,文件的权限不一定是可以改的
fileDir.setWritable(true);
//使用dirs是为了解决上传的路径中,如果有文件夹的没有创建,其会自动创建文件夹
fileDir.mkdirs();
}
if(!bakDir.exists()){
//使文件可以改,因为Tomcat发布服务后,文件的权限不一定是可以改的
bakDir.setWritable(true);
//使用dirs是为了解决上传的路径中,如果有文件夹的没有创建,其会自动创建文件夹
bakDir.mkdirs();
}
System.out.println(filePath);
Long total=map.get("size");
// while(total/3 !=0){
//
// }
//复制,需要按每20条复制
for(Map.Entry<String,Long> it : map.entrySet()){
// if(!"size".equals(it.getKey()))
fTPUtil.downloadFile( "/usr/ftp/file/", it.getKey(), filePath,".zip");
}
fTPUtil.closeFtp();
Map<String,Long> map2=new HashMap<String, Long>();
File[] listFiles = new File(filePath).listFiles();
if(listFiles.length>0){
for(File f:listFiles){
map2.put(f.getName().substring(0,f.getName().indexOf(".")), f.length());
}
}
Map<String,Boolean> map3=new HashMap<String, Boolean>();
for(Map.Entry<String,Long> it : map.entrySet()){
for(Map.Entry<String,Long> localFile : map2.entrySet()){
if(it.getKey().equals(localFile.getKey())){
if(it.getValue().equals(localFile.getValue())){
map3.put(it.getKey(), true);
}else{
map3.put(it.getKey(), false);
}
}else{
continue;
}
}
}
for(Map.Entry<String,Boolean> it : map3.entrySet()){
System.out.println("key:"+it.getKey()+",value="+it.getValue());
}
if(listFiles.length>0){
List<File> asList = Arrays.asList(listFiles);
Iterator<File> iterator = asList.iterator();
while(iterator.hasNext()){
File next = iterator.next();
fTPUtil.copyFile(next, new File(bakDir+File.separator+next.getName()));
// iterator.remove();
next.delete();
}
// for(File f:listFiles){
// f.delete();
// }
}
//下载并删除源文件,每20个一下载
// if("app")
//
//
}
public static void upload(MultipartFile file,String path){
String fileName = file.getOriginalFilename();
//扩展名
String fileExtensionName = fileName.substring(fileName.lastIndexOf('.')+1);
//使用UUID防止文件名重复,覆盖别人的文件
String uploadFileName = UUID.randomUUID().toString() + "." + fileExtensionName;
logger.info("开始上传文件,上传的文件名:{},上传的路径:{},新文件名:{} ",fileName,path,uploadFileName);
//新建文件
File fileDir = new File(path);
//判断文件是否存在,不存在就创建一个新的
if(!fileDir.exists()){
//使文件可以改,因为Tomcat发布服务后,文件的权限不一定是可以改的
fileDir.setWritable(true);
//使用dirs是为了解决上传的路径中,如果有文件夹的没有创建,其会自动创建文件夹
fileDir.mkdirs();
}
File targetFile = new File(path,uploadFileName);
try {
file.transferTo(targetFile);
//到此为止,文件已经上传服务器成功
//下一步是把文件上传到FTP服务器,与FTP文件服务器对接
FTPUtil.uploadFile(Lists.newArrayList(targetFile));
//已将文件上传FTP
//上传完之后,删除upload下面的文件
targetFile.delete();
} catch (IOException e) {
logger.error("上传文件异常",e);
}
}
}
ftpclient需要用到
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
上传用到
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>