关于ftp站点下载没有自动查找已有文件的BUG(轻量改进版)

之前写的博客是做一个简单的ftp工具类,但是简单的上传下载已经实现了,由于比较简单便改进了,之前是在util和Controller里调用就完事了,后面改进为在utils,service和controller里都走一遍,但是还是有问题,比如它下载时无论ftp有没有这个文件都会显示下载成功,有的话下载原文件,没有的话它会自动创建一个空的文本下载,比较头疼,后面改进了,引用了别人的代码,我就贴一下改进后的代码:

改进后的完整Utils类:

@Component
public class FTPUtils {
private static final Logger logger = LoggerFactory.getLogger(FTPUtils.class);

/**
 * 获取FTPClient对象
 *
 * @param ftpHost     FTP主机服务器
 * @param ftpPassword FTP 登录密码
 * @param ftpUserName FTP登录用户名
 * @param ftpPort     FTP端口 默认为21
 * @return
 */
public static FTPClient getFTPClient(String ftpHost, String ftpUserName,
                                     String ftpPassword, int ftpPort) {
    FTPClient ftpClient = new FTPClient();
    try {
        ftpClient = new FTPClient();
        ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
        ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
        if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
            System.out.println("未连接到FTP,用户名或密码错误。");
            ftpClient.disconnect();
        } else {
            System.out.println("FTP连接成功。");
        }
    } catch (SocketException e) {
        e.printStackTrace();
        System.out.println("FTP的IP地址可能错误,请正确配置。");
    } catch (IOException e) {
        e.printStackTrace();
        System.out.println("FTP的端口错误,请正确配置。");
    }
    return ftpClient;
}

/*
 * 从FTP服务器下载文件
 *
 * @param ftpHost FTP IP地址
 * @param ftpUserName FTP 用户名
 * @param ftpPassword FTP用户名密码
 * @param ftpPort FTP端口
 * @param ftpPath FTP服务器中文件所在路径 格式: ftptest/aa
 * @param localPath 下载到本地的位置 格式:H:/download
 * @param fileName 文件名称
 */
public static String downloadFtpFile(String ftpHost, String ftpUserName,
                                   String ftpPassword, int ftpPort, String ftpPath, String localPath,
                                   String fileName) {

    FTPClient ftpClient = null;

    try {
        ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
        ftpClient.setControlEncoding("UTF-8"); // 中文支持
        ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
        //String file = ftpPath.substring(ftpPath.lastIndexOf("/") + 1);
        ftpClient.enterLocalPassiveMode();
        ftpClient.changeWorkingDirectory(ftpPath);

        **InputStream is = ftpClient.retrieveFileStream(new String(fileName.getBytes("GBK"),ftpClient.DEFAULT_CONTROL_ENCODING));
        if(is == null || ftpClient.getReplyCode()== FTPReply.FILE_UNAVAILABLE){
            return "对不起,没有指定的文件";
        }
        if(is != null) {**加粗样式**
            File localFile = new File(localPath + File.separatorChar + fileName);
            OutputStream os = new FileOutputStream(localFile);
            ftpClient.retrieveFile(fileName, os);
            os.close();
            is.close();
            ftpClient.completePendingCommand();
        }
        return fileName+"下载成功";**
    } catch (FileNotFoundException e) {
        System.out.println("没有找到" + ftpPath + "文件");
        e.printStackTrace();
        return "没有找到" + ftpPath + "文件";
    } catch (SocketException e) {
        System.out.println("连接FTP失败.");
        e.printStackTrace();
        return "连接FTP失败.";
    } catch (IOException e) {
        e.printStackTrace();
        System.out.println("文件读取错误。");
        e.printStackTrace();
        return "文件读取错误。";
    }finally {
        if(ftpClient != null){
            try {
                ftpClient.disconnect();
            }catch (IOException e){
                logger.error(e.getMessage());
            }
        }
    }
}

/**
 * Description: 向FTP服务器上传文件
 * @param ftpHost FTP服务器hostname
 * @param ftpUserName 账号
 * @param ftpPassword 密码
 * @param ftpPort 端口
 * @param ftpPath  FTP服务器中文件所在路径 格式: ftptest/aa
 * @param fileName ftp文件名称
 * @param input 文件流
 * @return 成功返回true,否则返回false
 */
public static boolean uploadFile(String ftpHost, String ftpUserName,
                                 String ftpPassword, int ftpPort, String ftpPath,
                                 String fileName,InputStream input) {
    boolean success = false;
    FTPClient ftpClient = null;
    try {
        int reply;
        ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
        reply = ftpClient.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            ftpClient.disconnect();
            return success;
        }
        ftpClient.setControlEncoding("UTF-8"); // 中文支持
        ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
        ftpClient.enterLocalPassiveMode();
        ftpClient.changeWorkingDirectory(ftpPath);

        ftpClient.storeFile(fileName, input);

        input.close();
        ftpClient.logout();
        success = true;
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (ftpClient.isConnected()) {
            try {
                ftpClient.disconnect();
            } catch (IOException ioe) {
            }
        }
    }
    return success;
}

}

改进的后的Service代码:

@Service
public class FtpService {
@Autowired
private FTPUtils ftpUtils;
private static final Logger logger = LoggerFactory.getLogger(FtpService.class);

//由于下载和上传ftp服务器的地址可能不一致,所以下载和上传的ftp地址分开
@Value("${ftphost}")
private String ftpHost;
@Value("${ftpusername}")
private String ftpUserName;
@Value("${ftppassword}")
private String ftpPassword;
@Value("${ftpport}")
private String ftpPort;
@Value("${ftppath}")
private String ftpPath;
@Value("${ftplocalpath}")
private String localPath;



/**
 * ftp文件上传
 * @param file 需要上传的文件
 * @return
 * @throws IOException
 */
public String Upload(MultipartFile file) throws IOException {
    String filename = file.getOriginalFilename();
    InputStream inputStream = file.getInputStream();
    boolean flag= ftpUtils.uploadFile( "192.168.43.84",  "fanyusong","123456",  21,"/",filename, inputStream);
    if (flag){
        return "上传成功";
    }
    return "上传失败";
}

/**
 * ftp文件下载
 * @param fileName ftp需要下载的文件名
 * @return
 */
public String Download(String fileName){
   int ftpPathInt = Integer.parseInt(ftpPort);
   return ftpUtils.downloadFtpFile(ftpHost, ftpUserName,ftpPassword,ftpPathInt,ftpPath,localPath, fileName);
}

}

改进后的Controller代码:

@RestController
@RequestMapping("/ftp")
public class FtpController {

@Autowired
private FtpService ftpService;


@ApiOperation(value = "ftp上传", notes = "ftp上传")
@PostMapping("/upfile")
public JsonResponse Upload(MultipartFile file) throws Exception {
    return JsonResponseUtil.success(ftpService.Upload(file));
}

/**
 * ftp下载
 * @param fileName
 * @return
 * @throws Exception
 */
@ApiOperation(value = "ftp下载", notes = "ftp下载")
@GetMapping("/downfile")
public JsonResponse Download(@RequestParam String fileName) throws Exception {
    return JsonResponseUtil.success(ftpService.Download(fileName));
    }
}

重新配置的yml文件:

#ftp下载地址配置
ftphost: 192.168.43.84
ftpusername: fanyusong
ftppassword: 123456
ftpport: 21
ftppath: “/”
ftplocalpath: F:\FTPDownload

因为之前是用依赖包,但是相反的加重了代码还不好管理配置,所以此处删除了依赖
本人是做一个功能写一篇博客,别的不说,每次遇到问题网上各种找思路,很累,因为没有完全相同的需求,我写一些也让别人有相似的需求的时候可以参考一下,都是学习路上踩坑的人,相互学习借鉴让路没有那么难走
越努力越幸运,加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值