vsftp文件服务器的搭建与使用案例

一、Linux 云服务器搭建 FTP 服务

1.执行以下命令,安装 vsftpd。

yum install -y vsftpd

2.执行以下命令,设置 vsftpd 开机自启动。

systemctl enable vsftpd

3.执行以下命令,启动 FTP 服务

systemctl start vsftpd

4.执行以下命令,确认服务是否启动

netstat -antup | grep ftp

5.配置 vsftpd

5.1.执行以下命令,为 FTP 服务创建一个 Linux 用户,本文以 ftpuser 为例。

useradd ftpuser

5.2.执行以下命令,设置 ftpuser 用户的密码

passwd ftpuser

5.3.执行以下命令,创建 FTP 服务使用的文件目录,本文以 /var/ftp/test 为例。

mkdir /var/ftp/test

5.4.执行以下命令,修改目录权限

chown -R ftpuser:ftpuser /var/ftp/test

5.6.执行以下命令,打开 vsftpd.conf 文件

vim /etc/vsftpd/vsftpd.conf

5.7.修改以下配置参数

主动模式配置:

anonymous_enable=NO
local_enable=YES
write_enable=YES
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
listen=YES
#listen_ipv6=YES

被动模式配置:

local_root=/var/ftp/test
allow_writeable_chroot=YES
pasv_enable=YES
pasv_address=xxx.xx.xxx.xx #请修改为您的 Linux 云服务器公网 IP
pasv_min_port=40000
pasv_max_port=45000

 按Esc 后输入 :wq 保存后退出.

5.8.执行以下命令,重启 FTP 服务。

systemctl restart vsftpd

安装教程参考如下地址:云服务器 Linux 云服务器搭建 FTP 服务-最佳实践-文档中心-腾讯云

FTP客户端下载:FileZilla中文网 - 免费开源的FTP解决方案

二、使用教程

建立连接:

//需要连接到的ftp端的ip
    @Value(value = "${ftp.ip}")
    private String ip;

    //连接端口,默认21
    @Value(value = "${ftp.prot}")
    private int port;

    //要连接到的ftp端的名字
    @Value(value = "${ftp.username}")
    private String name;

    //要连接到的ftp端的对应得密码
    @Value(value = "${ftp.password}")
    private String pwd;

    @Value(value = "${ftp.ftpUrl}")
    private String ftpUrl;
    //ftp对象
    private FTPClient ftp;

/**
     * 1.连接ftp
     * 调用此方法,输入对应得ip,端口,要连接到的ftp端的名字,要连接到的ftp端的对应得密码。连接到ftp对象,并验证登录进入fto
     */
    public boolean ftp1() {
        ftp = new FTPClient();
        try {
            if (!ftp.isConnected()) {
                ftp.connect(ip, port);
            }
            log.info("连接状态:" + ftp.login(name, pwd));

            ftp.setCharset(Charset.forName("UTF-8"));
            ftp.setControlEncoding("UTF-8");
//            ftp.enterLocalActiveMode();    //主动模式
            ftp.enterLocalPassiveMode();        // 被动模式
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

 public CommonResultVo threeDAndEightDReports() {
        //抱怨单号、FTP地址、3D/8D文件类型
        log.info("-------------ftpUrl地址:" + ip);
        boolean flag = this.ftp1();  //1.连接FTP
        if (flag) {
            try {
                this.gmRead(ftpUrl); //2.获取文件、解析文件内容,进库操作
                this.disconnect();  //3. 关闭连接
                return CommonResultVo.failed("FTP数据发送MQ完成");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return CommonResultVo.failed("连接FTP失败");
    }
 /**
     * 2.获取文件、解析文件内容,进库操作
     */
    public void gmRead(String ftpUrl) throws IOException {

        boolean downloadResult = false;
        try {
            ftp.changeWorkingDirectory(ftpUrl);
            log.info("远程路径为*************************" + ftpUrl);

            FTPFile[] files = ftp.listFiles(ftpUrl); // 通过路径得到文件
            log.info("文件数量为*************************" + files.length);

            for (int i = 0; i < files.length; i++) {
                FTPFile file = files[i];
                if (file.isFile()) {
//                    downloadResult = this.download(file);// 下载文件 到本地读取路径
//                    this.downloadFtpFile(file);
                    new FTPDownload().downloadToFileAll(ftp, ftpUrl);
                } else {
                    log.info("************* 文件不存在 ************");
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

文件下载:

import static com.cetc.service.impl.MessageServicesImpl.pathStr;

/**
 * @author :jerry
 * @date :Created in 2022/10/25 11:04
 * @description:FTP文件下载
 * @version: V1.1
 */
@Slf4j
public class FTPDownload {

    //下载存放路径
    public static final String pathStr = Paths.get("upload").toAbsolutePath().toString();
    private FTPClient ftp;

    /**
     * 1.普通下载
     */
    public synchronized void downloadToFile(FTPClient ftp, String pathname, String filename) throws IOException {
        //删除文件
        File directory = new File(pathStr);
        Files.walk(directory.toPath()).filter(Files::isRegularFile).map(Path::toFile).forEach(File::delete);
        log.info("删除"+pathStr+"目录下的所有历史文件成功");

        try {
            this.ftp = ftp;
            //切换FTP目录
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            ftp.changeWorkingDirectory(pathname);
            FTPFile[] ftpFiles = ftp.listFiles();
            for (FTPFile file : ftpFiles) {
                if (filename.equalsIgnoreCase(file.getName())) {
                    File localFile = new File(pathStr + "/" + filename);
                    OutputStream is = new FileOutputStream(localFile);
                    ftp.retrieveFile(file.getName(), is);
                    is.close();
                    break;
                }
            }
            ftp.logout();
            log.info("下载文件成功");
        } catch (Exception e) {
            log.error("下载文件失败");
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 2.字节流的形式下载文件
     */
    public ByteArrayOutputStream byteDownloadZip(FTPClient ftp, FTPFile filePath) {
        this.ftp = ftp;
        ByteArrayOutputStream bos = null;
        try {
            //切换FTP目录
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            ftp.changeWorkingDirectory(pathStr);
            FTPFile[] ftpFiles = ftp.listFiles();
            String filename = filePath.getName();
            for (FTPFile file : ftpFiles) {
                if (filename.equalsIgnoreCase(file.getName())) {
                    InputStream is = ftp.retrieveFileStream(filename);
                    bos = new ByteArrayOutputStream();
                    int len = 0;
                    byte[] buffer = new byte[1024];
                    while ((len = is.read(buffer)) > 0) {
                        bos.write(buffer, 0, len);
                    }
                    bos.flush();
                    bos.close();
                    is.close();
                    ftp.completePendingCommand();
                    break;
                }
            }
            ftp.logout();
            log.info("下载文件成功");
        } catch (Exception e) {
            log.error("下载文件失败");
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println(bos);
        return bos;

    }

    /**
     * 下载全部FTP文件目录文件
     * */
    public synchronized void downloadToFileAll(FTPClient ftp, String pathname) {
        try {
            this.ftp = ftp;
            //切换FTP目录
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            ftp.changeWorkingDirectory(pathname);
            FTPFile[] ftpFiles = ftp.listFiles();
            for (FTPFile file : ftpFiles) {
                String filename = file.getName();
                log.info("filename:"+filename);
                File localFile = new File(pathStr + "/" + filename);
                OutputStream is = new FileOutputStream(localFile);
                ftp.retrieveFile(file.getName(), is);
                is.close();
            }
            ftp.logout();
            log.info("下载文件成功");
        } catch (Exception e) {
            log.error("下载文件失败");
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;


@Getter
@Setter
@Builder
public class CommonResultVo<T> {

    private int code;
    private String message;
    private T data;

    protected CommonResultVo() {
    }

    protected CommonResultVo(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    /**
     * 成功返回结果
     *
     */
    public static <T> CommonResultVo<T> success() {
        return new CommonResultVo<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), null);
    }

    /**
     * 成功返回结果
     *
     * @param data 获取的数据
     */
    public static <T> CommonResultVo<T> success(T data) {
        return new CommonResultVo<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
    }

    /**
     * 成功返回结果
     *
     * @param data 获取的数据
     * @param  message 提示信息
     */
    public static <T> CommonResultVo<T> success(T data, String message) {
        return new CommonResultVo<T>(ResultCode.SUCCESS.getCode(), message, data);
    }

    /**
     * 失败返回结果
     * @param resultCode 错误码
     */
    public static <T> CommonResultVo<T> failed(ResultCode resultCode) {
        return new CommonResultVo<T>(resultCode.getCode(), resultCode.getMessage(), null);
    }

    /**
     * 失败返回结果
     * @param resultCode 错误码
     * @param message 错误信息
     */
    public static <T> CommonResultVo<T> failed(ResultCode resultCode, String message) {
        return new CommonResultVo<T>(resultCode.getCode(), message, null);
    }

    /**
     * 失败返回结果
     * @param message 提示信息
     */
    public static <T> CommonResultVo<T> failed(String message) {
        return new CommonResultVo<T>(ResultCode.FAILED.getCode(), message, null);
    }

    /**
     * 失败返回结果
     */
    public static <T> CommonResultVo<T> failed() {
        return failed(ResultCode.FAILED);
    }
}

 

import lombok.Getter;
import lombok.Setter;


public enum ResultCode {
    SUCCESS(0, "操作成功"),
    FAILED(-1, "操作失败"),
    VALIDATE_FAILED(404, "参数检验失败"),
    UNAUTHORIZED(401, "暂未登录或token已经过期"),
    FORBIDDEN(403, "没有相关权限");

    @Setter
    @Getter
    private int code;

    @Setter
    @Getter
    private String message;

    private ResultCode(int code, String message) {
        this.code = code;
        this.message = message;
    }


}

yml配置如下:

#个人测试
ftp:
  ip: 10.10.10.121   #IP
  prot: 21  #端口
  ftpUrl: /   #文件路径
  username: ftpuser   #用户名
  password: 123456   #密码

 

注意:

ftp.changeWorkingDirectory(pathname);    //是切换到你的文件所在的目录,如果文件不在根目录,下载下来可能为0kb

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值