项目采用的是springboot,依赖管理工具用的是gradle,配置文件是yml文件
1.导入相关ftp需要的jar包
dependencies {
compile group: ‘commons-net’, name: ‘commons-net’, version: “3.6”}
2.创建ftp相关的配置类
@ConfigurationProperties(prefix = “ftp”)
@Data
public class FTPConfigProperties {
private String address;
private int port;
private String username;
private String password;
private String localFilePath;
}
3.创建ftp相关的utils
@Slf4j
public class FTPFileManager {
private String address;
private int port;
private String username;
private String password;
private String localFilePath;
//different company's files save different foladers
public FTPFileManager(String companyName, FTPConfigProperties ftpConfigProperties) {
this.ftpRoot = "/" + companyName + "/";
address = ftpConfigProperties.getAddress();
port = ftpConfigProperties.getPort();
username = ftpConfigProperties.getUsername();
password = ftpConfigProperties.getPassword();
localFilePath = ftpConfigProperties.getLocalFilePath();
}
// file's path
private String ftpRoot;
private FTPClient readFTP;
private List<File> files = new ArrayList<>();
private List<File> doneFiles = new ArrayList<>();
private List<File> errorFiles = new ArrayList<>();
// fetch files from ftp
public List<File> fetch() throws IOException {
this.readFTP = this.connect();
readFTP.changeWorkingDirectory(ftpRoot);
FTPFile[] files = readFTP.listFiles();
for (FTPFile file : files) {
if (file.getName().contains(".csv")) {
File localFile = new File(localFilePath + file.getName());
FileOutputStream os = new FileOutputStream(localFile);
try {
readFTP.retrieveFile(file.getName(), os);
this.files.add(localFile);
} catch (IOException e) {
log.error("error", e);
} finally {
os.close();
}
}
}
return this.files;
}
public void fileDone(File file) {
doneFiles.add(file);
}
public void fileError(File file) {
errorFiles.add(file);
}
public void clean() throws IOException {
try {
for(File file :this.doneFiles) {
readFTP.changeWorkingDirectory(ftpRoot + Folder.DONE);
boolean moved = readFTP.rename(ftpRoot + file.getName(), file.getName());
log.info("{} moved to done:{}", file.getName(), moved);
}
for (File file : this.errorFiles) {
readFTP.changeWorkingDirectory(ftpRoot + Folder.ERROR);
boolean moved = readFTP.rename(ftpRoot + file.getName(), file.getName());
log.info("{} moved to error:{}", file.getName(), moved);
}
for (File file : this.files) {
boolean deleted = file.delete();
if (!deleted) {
log.warn("{} temp file was not deleted", file.getAbsolutePath() + file.getName());
}
}
}catch(IOException io) {
log.error("====moved file error =====");
}finally {
readFTP.disconnect();
}
}
private FTPClient connect() throws IOException {
FTPClient ftpClient = new FTPClient();
try {
ftpClient.setControlEncoding("UTF-8");
ftpClient.connect(address, port);
ftpClient.login(username, password);
int replyCode = ftpClient.getReplyCode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
if (!FTPReply.isPositiveCompletion(replyCode)) {
ftpClient.disconnect();
log.info("=====连不上ftp,惨了====,返回的code信息为:[{}]", replyCode);
throw new IOException();
}
return ftpClient;
} catch (IOException e) {
log.info("======连接ftp异常,异常信息为:[{}],causer为:[{}]======", e.getMessage(), e.getCause());
throw e;
}
}
//定义枚举类型,来区分文件的状态
enum Folder {
NEW,
DONE,
ERROR
}
}