近期遇到的和FTP有关的问题

 近期在处理ftp文件上传是遇到的一系列问题,今天在此简单的罗列一下,希望大家可以借鉴.

 第一类问题,ftp可以连接但是上传始终返回失败:

在上传文件前添加一行代码 ftpClient.enterLocalPassiveMode(); 设置FTP模式为被动模式。(主被动模式的区别大家可以自行百度了解一下)FTP支持两种模式,一种方式叫做Standard (也就是 PORT方式,主动方式),一种是 Passive (也就是PASV,被动方式)。

第二类问题是,ftp创建文件夹失败:

造成这种问题的原因主要是文件夹的权限问题 

首先在ftp的目录中创建一个目录,然后设置权限为777 $ sudo mkdir /var/ftp/write $ sudo chmod -R 777 /var/ftp/write 然后修改vsftp的配置文件/etc/vsftpd.conf文件 在最后添加上 local_root=/var/ftp 保存,然后杀死vsftpd进程,然后重启vsftpd服务器程序。 试试看,将文件上传到write目录,这个时候可以正常的上传文件了。

 另一个原因是文件所有者和文件所在组不对应

chgrp  用户名    文件名  -R

chown 用户名   文件名  -R

-R表示递归目录下所有文件

以上部分已验证

 

下面是ftp相关的工具类

public class FTPUtils {
    protected static Log logger = LogFactory.getLog(FTPUtils.class);
    private static FTPUtils ftpUtils;
    private static FTPClient ftpClient;

    private static String port; // 服务器端口
    private static String username; // 用户登录名
    private static String password; // 用户登录密码
    private static InputStream is; // 文件下载输入流
    // 图文详情HTML存储路径
    public static String detailPath = "/resources/static/topic/details/";

    /**
     * 私有构造方法
     */
    public FTPUtils() {
        initConfig();
        if (null == ftpClient) {
            ftpClient = new FTPClient();
        }
    }

    /**
     * 获取FTPUtils对象实例
     * 
     * @return FTPUtils对象实例
     */
    public synchronized static FTPUtils getInstance() {
        if (null == ftpUtils) {
            ftpUtils = new FTPUtils();
        }
        return ftpUtils;
    }

    /**
     * 初始化FTP服务器连接属性
     */
    public void initConfig() {
        // 构造Properties对象
        Properties properties = new Properties();

        // 定义配置文件输入流
        InputStream is = null;
        try {
            // 获取配置文件输入流
            is = FTPUtils.class.getClassLoader().getResourceAsStream("ftp.properties");
            // 加载配置文件
            properties.load(is);
            // 读取配置文件
            port = (String) properties.get("port"); // 设置端口
            username = (String) properties.get("username"); // 设置用户名
            password = (String) properties.get("password"); // 设置密码
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 判断输入流是否为空
            if (null != is) {
                try {
                    // 关闭输入流
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 连接(配置通用连接属性)至服务器
     * 
     * @param serverName
     *            服务器名称
     * @param remotePath
     *            当前访问目录
     * @return <b>true</b>:连接成功 <br/>
     *         <b>false</b>:连接失败
     */
    public static boolean connectToTheServer(String serverName, String remotePath) {
        // 定义返回值
        boolean result = false;
        try {
            logger.debug("serverName:" + serverName + ", remotePath:" + remotePath);
            logger.debug("port:" + port + ", username:" + username + ", password:" + password);
            // 连接至服务器,端口默认为21时,可直接通过URL连接
            ftpClient.connect(serverName, Integer.parseInt(port));

            // 登录服务器
            ftpClient.login(username, password);
            // 判断返回码是否合法
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                // 不合法时断开连接
                ftpClient.disconnect();
                // 结束程序
                return result;
            }
            // 设置文件操作目录
            result = ftpClient.changeWorkingDirectory(remotePath);
            // 如果设置操作目录失败,则路径可能不存在,执行创建路径接口在设置操作目录
            if (!result) {
                // 判断当前路径是否存在,不存在直接创建
                makeDirectory(remotePath);
                result = ftpClient.changeWorkingDirectory(remotePath);
            }
            // 设置文件类型,二进制
            result = ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            // 设置缓冲区大小
            ftpClient.setBufferSize(3072);
            // 设置字符编码
            ftpClient.setControlEncoding("UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 根据路径创建文件夹 ftp不支持多级文件夹创建,所以循环创建
     * 
     * @param storePath
     * @return
     */
    public static boolean makeDirectory(String storePath) {
        String[] st = storePath.split("/");
        String path = "";
        try {
            for (int i = 0; i < st.length; i++) {
                if (i == 0) {
                    path = path + "/" + st[i];
                } else {
                    path = path + "/" + st[i];
                }
                boolean b = ftpClient.makeDirectory(path);
                if (!b) {
                    logger.info("创建ftp多级路径失败!");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return true;
    }

    /**
     * 上传文件至FTP服务器
     * 
     * @param serverName
     *            服务器名称
     * @param storePath
     *            上传文件存储路径
     * @param fileName
     *            上传文件存储名称
     * @param is
     *            上传文件输入流
     * @return <b>true</b>:上传成功 <br/>
     *         <b>false</b>:上传失败
     */
    public static boolean storeFile(String serverName, String storePath, String fileName, InputStream is) {
        boolean result = false;
        try {
            logger.debug("storeFile: storePath:" + storePath + ", fileName:" + fileName);
            
            // 连接至服务器
            result = connectToTheServer(serverName, storePath);
            logger.debug("storeFile-------------------: serverName:" + serverName + ", 连接result:" + result);
            // 判断服务器是否连接成功
            if (result) {
                // 设置文件的传输类型,默认是ASCII,修改为二进制  
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                logger.debug(" ftpClient.setFileType(FTP.BINARY_FILE_TYPE);" );
                // 上传文件
                ftpClient.enterLocalPassiveMode();
                result = ftpClient.storeFile(fileName, is);
                logger.debug("上传result---------------------" + result);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 判断输入流是否存在
            if (null != is) {
                try {
                    // 关闭输入流
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 登出服务器并断开连接
            ftpUtils.logout();
        }
        return result;
    }

    /**
     * 下载FTP服务器文件至本地<br/>
     * 操作完成后需调用logout方法与服务器断开连接
     * 
     * @param serverName
     *            服务器名称
     * @param remotePath
     *            下载文件存储路径
     * @param fileName
     *            下载文件存储名称
     * @return <b>InputStream</b>:文件输入流
     */
    public static InputStream retrieveFile(String serverName, String remotePath, String fileName) {
        try {
            boolean result = false;
            // 连接至服务器
            result = connectToTheServer(serverName, remotePath);
            // 判断服务器是否连接成功
            if (result) {
                // 获取文件输入流
                is = ftpClient.retrieveFileStream(fileName);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return is;
    }

    /**
     * 删除FTP服务器文件
     * 
     * @param serverName
     *            服务器名称
     * @param remotePath
     *            当前访问目录
     * @param fileName
     *            文件存储名称
     * @return <b>true</b>:删除成功 <br/>
     *         <b>false</b>:删除失败
     */
    public static boolean deleteFile(String serverName, String remotePath, String fileName) {
        boolean result = false;
        // 连接至服务器
        result = connectToTheServer(serverName, remotePath);
        // 判断服务器是否连接成功
        if (result) {
            try {
                // 删除文件
                result = ftpClient.deleteFile(fileName);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // 登出服务器并断开连接
                ftpUtils.logout();
            }
        }
        return result;
    }

    /**
     * 检测FTP服务器文件是否存在
     * 
     * @param serverName
     *            服务器名称
     * @param remotePath
     *            检测文件存储路径
     * @param fileName
     *            检测文件存储名称
     * @return <b>true</b>:文件存在 <br/>
     *         <b>false</b>:文件不存在
     */
    public boolean checkFile(String serverName, String remotePath, String fileName) {
        boolean result = false;
        try {
            // 连接至服务器
            result = connectToTheServer(serverName, remotePath);
            // 判断服务器是否连接成功
            if (result) {
                // 默认文件不存在
                result = false;
                // 获取文件操作目录下所有文件名称
                String[] remoteNames = ftpClient.listNames();
                // 循环比对文件名称,判断是否含有当前要下载的文件名
                for (String remoteName : remoteNames) {
                    if (fileName.equals(remoteName)) {
                        result = true;
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 登出服务器并断开连接
            ftpUtils.logout();
        }
        return result;
    }

    /**
     * 登出服务器并断开连接
     * 
     * @param ftp
     *            FTPClient对象实例
     * @return <b>true</b>:操作成功 <br/>
     *         <b>false</b>:操作失败
     */
    public boolean logout() {
        boolean result = false;
        if (null != is) {
            try {
                // 关闭输入流
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != ftpClient) {
            try {
                // 登出服务器
                result = ftpClient.logout();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // 判断连接是否存在
                if (ftpClient.isConnected()) {
                    try {
                        // 断开连接
                        ftpClient.disconnect();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return result;
    }

    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

    /**
     * 读取html内容内容
     * 
     * @param path
     *            需要读取的文件地址
     * @return
     * @throws IOException
     */
    public String getBodyString(String path) throws IOException {
        String data = "";
        try {
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            InputStream inputStream = conn.getInputStream(); // 通过输入流获得网站数据
            byte[] getData = readInputStream(inputStream); // 获得网站的二进制数据
            data = new String(getData, "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * 返回FTP目录下的文件列表
     * @param ftpDirectory
     * @return
     */
     public static List<FTPFile> getFileNameList(String serverName,String ftpDirectory) 
     { 
        List<FTPFile> list = new ArrayList<FTPFile>(); 
        boolean result = connectToTheServer(serverName, ftpDirectory);
        if(!result)
        	return list;
        try  
        { 
        	 ftpClient.enterLocalPassiveMode();
        	 FTPFile[] ftpfiles = ftpClient.listFiles(ftpDirectory);
        	 logger.debug("ftpfiles---------------------" + ftpfiles.length);
        	    for(FTPFile file : ftpfiles){
        	    	list.add(file);
        	     }
        } catch (Exception e)  
        { 
           e.printStackTrace(); 
        } 
        return list; 
     }
}

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值