ftp上传的文件为先zip,再gz的文件。在将文件传送至s3的过程中,需要对第一层zip进行解压,保留第二层gz解压。默认的gz文件没有后缀名,在上传至s3时需要增加gz文件后缀名。 如果该文件从未上传至S3,则将该文件按照上一章节的要求解压缩,并上传至S3。上传成功后在数据库中记录。 如果数据库记录表明该文件已经上传过S3,则忽略
下载部分代码 控制层:
@PostMapping("/download")
public R download(){
R download = ftpService.download();
return download;
}
service层:
R download();
实现层:
public R download() {
String fileName = null;
//先获取该文件路径下所有的文件夹List
List<String> fileNamePathList = FtpUtils.ftpListFiles(ftpConfig.getUrl(), ftpConfig.getPort(), ftpConfig.getUsername(),
ftpConfig.getPassword(), ftpConfig.getRemotePath());
// 拿到真正的文件
List<String> fileNameList = new ArrayList<>();
List<String> fileNames = new ArrayList<>();
//遍历这些文件夹获取到所有文件名并拼接上
for(String str : fileNamePathList){
List<String> list = FtpUtils.ftpListFiles(ftpConfig.getUrl(), ftpConfig.getPort(), ftpConfig.getUsername(),
ftpConfig.getPassword(), str);
fileNameList.addAll(list);
}
// 截取文件名
List<String> fileList = new ArrayList<>();
for(String filePath : fileNameList){
fileList.add(filePath.substring(filePath.lastIndexOf("/",filePath.lastIndexOf("/")-1)));
}
Iterator<String> iterator = fileNameList.iterator();
Iterator<String> iterator1= fileList.iterator();
while (iterator.hasNext()&&iterator1.hasNext()){
String filePath= iterator.next();
iterator1.next();
fileName = filePath.substring(filePath.lastIndexOf("/")+1);
String byFileName = userBillRepository.findByName(fileName);
String remotePath = filePath.substring(0, filePath.lastIndexOf("/")+1);
if(byFileName==null){
boolean result = FtpUtils.ftpDownload(fileName, ftpConfig.getUrl(),ftpConfig.getPort(),ftpConfig.getUsername(),
ftpConfig.getPassword(), remotePath, ftpConfig.getDownDir());
if (result) {
UserBillEntity userBill = new UserBillEntity();
userBill.setBillDate(fileName.substring(0,8));
userBill.setFileName(fileName);
fileNames.add(fileName);
userBill.setIsUpload(0);
userBill.setIsVerification(1);
userBillRepository.save(userBill);
log.info("=======下载文件"+ fileName +"成功=======");
} else{
log.info("=======下载文件"+ fileName +"失败=======");
R.fail("下载文件失败");
}
}else {
Integer isUpload = userBillRepository.findUpload(fileName);
if(isUpload==0){
try {
boolean result = FtpUtils.ftpDownload(fileName, ftpConfig.getUrl(),ftpConfig.getPort(),ftpConfig.getUsername(),
ftpConfig.getPassword(), remotePath, ftpConfig.getDownDir());
} catch (Exception e) {
log.info("下载报错了....{}", e.getMessage());
}
}else{
iterator1.remove();
}
}
}
R r = uploadFileService.findFile(ftpConfig.getDownDir(),ftpConfig.getRemotePath(),fileList,fileNames);
return r;
}
工具类:
public class FtpUtils {
private static FTPClient mFTPClient = new FTPClient();
private static FtpUtils ftp = new FtpUtils();
public FtpUtils() {
// 在控制台打印操作过程
mFTPClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
}
/**
* 从ftp服务器下载文件到本地
*/
public static boolean ftpDownload(String fileName, String ftpUrl, int ftpPort,
String ftpUsername, String ftpPassword, String ftpRemotePath, String ftpDownDir) {
boolean result = false;
try {
boolean isConnection = ftp.openConnection(ftpUrl, ftpPort, ftpUsername, ftpPassword);
if (isConnection) {
boolean isDownloadOk = ftp.downLoad(ftpRemotePath,ftpDownDir,fileName);
boolean isCreateOk = ftp.createDirectory(ftpRemotePath, ftp.mFTPClient);
if (isDownloadOk && isCreateOk) {
log.info("文件下载成功!");
result = true;
} else {
log.info("文件下载失败!");
result = false;
}
ftp.logout();
} else {
log.info("链接ftp服务器失败,请检查配置信息是否正确!");
result = false;
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 连接ftp服务器
*
* @param host
* ip地址
* @param port
* 端口号
* @param account
* 账号
* @param pwd
* 密码
* @return 是否连接成功
* @throws SocketException
* @throws IOException
*/
public boolean openConnection(String host, int port, String account, String pwd)
throws SocketException, IOException {
mFTPClient.setControlEncoding("UTF-8");
mFTPClient.connect(host, port);
if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) {
mFTPClient.login(account, pwd);
if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) {
System.err.println(mFTPClient.getSystemType());
FTPClientConfig config = new FTPClientConfig(mFTPClient.getSystemType().split(" ")[0]);
//FTPClientConfig config = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
config.setServerLanguageCode("zh");
mFTPClient.configure(config);
return true;
}
}
disConnection();
return false;
}
/**
* 登出并断开连接
*/
public void logout() {
System.err.println("logout");
if (mFTPClient.isConnected()) {
System.err.println("logout");
try {
mFTPClient.logout();
disConnection();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 断开连接
*/
private void disConnection() {
if (mFTPClient.isConnected()) {
try {
mFTPClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 下载文件到本地地址
*
* @param ftpRemotePath
* 远程地址
* @param localDir
* 本地地址
* @throws IOException
*/
public boolean downLoad(String ftpRemotePath,String localDir,String filename) throws IOException {
// 进入被动模式
if(ftpRemotePath.endsWith("/")){
ftpRemotePath=ftpRemotePath + filename;
}else{
ftpRemotePath=ftpRemotePath + "/"+ filename;
}
mFTPClient.enterLocalPassiveMode();
// 以二进制进行传输数据
mFTPClient.setFileType(FTP.ASCII_FILE_TYPE);
FTPFile[] ftpFiles = mFTPClient.listFiles(ftpRemotePath);
if (ftpFiles == null|| ftpFiles.length == 0) {
log.info("远程文件不存在");
return false;
} else if (ftpFiles.length > 1) {
log.info("远程文件是文件夹");
return false;
}
long lRemoteSize = ftpFiles[0].getSize();
// 本地文件的地址
File localFileDir = new File(localDir);
if (!localFileDir.exists()) {
localFileDir.mkdirs();
}
File localFile = new File(localFileDir, ftpFiles[0].getName());
long localSize = 0;
FileOutputStream fos = null;
if (localFile.exists()) {
if (localFile.length() == lRemoteSize) {
System.err.println("已经下载完毕");
return true;
} else if (localFile.length() < lRemoteSize) {
// 传要下载的文件存在,进行断点续
localSize = localFile.length();
mFTPClient.setRestartOffset(localSize);
fos = new FileOutputStream(localFile, true);
}
}
if (fos == null) {
fos = new FileOutputStream(localFile);
}
//此处必须添加编码集设置,否则可能会有is空指针的bug
InputStream is = mFTPClient.retrieveFileStream(new String(ftpRemotePath.getBytes("UTF-8"), "ISO-8859-1"));
byte[] buffers = new byte[1024];
long step = lRemoteSize / 10;
long process = localSize / step;
int len = -1;
while ((len = is.read(buffers)) != -1) {
fos.write(buffers, 0, len);
localSize += len;
long newProcess = localSize / step;
if (newProcess > process) {
process = newProcess;
System.err.println("下载进度:" + process);
}
}
fos.close();
is.close();
boolean isDo = mFTPClient.completePendingCommand();
if (isDo) {
System.err.println("下载成功");
} else {
System.err.println("下载失败");
}
return isDo;
}
//接收ftp文件路径和路径下的所有文件夹或文件
//拼接RemotePath路径+路径下的文件夹 或RemotePath+路径下文件夹+文件名
public static List<String> getAllFilePath(String ftpRemotePath, FTPFile[] ftpFiles){
ArrayList<String> fileNameList = new ArrayList<>();
for(int i=0; i<ftpFiles.length; i++){
FTPFile ftpFile = ftpFiles[i];
//endWith()方法判断传过来的路径底下是否还有文件夹
//传来路径末尾是"/"表示路径下还有文件夹,否则表示已经精确到具体文件夹拼接具体文件名即可
if(ftpRemotePath.endsWith("/")){
fileNameList.add(ftpRemotePath + ftpFile.getName());
}else{
fileNameList.add(ftpRemotePath + "/" + ftpFile.getName());
}
}
return fileNameList;
}
/**
* 列举ftp服务器文件,根据ftp远程路径
*/
public static List<String> ftpListFiles(String ftpUrl, int ftpPort, String ftpUsername,String ftpPassword, String ftpRemotePath) {
List<String> allFilename = new ArrayList<>();
try {
boolean isConnection = ftp.openConnection(ftpUrl, ftpPort, ftpUsername, ftpPassword);
if (isConnection) {
// 进入被动模式
mFTPClient.enterLocalPassiveMode();
//获取RemotePath路径下的所有文件夹或者文件
FTPFile[] ftpFiles = mFTPClient.listFiles(ftpRemotePath);
allFilename = getAllFilePath(ftpRemotePath, ftpFiles);
ftp.logout();
} else {
log.info("连接ftp服务器失败,请检查配置信息是否正确!");
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return allFilename;
}
}
}