`

ftp实现上传下载,解决了编码问题

阅读更多

 很多人都碰到ftp的上传下载文件的实现,很容易碰到一些问题,最难解决的是乱码的问题,
在网上搜索了挺多,也没人能讲得清楚详细的,这里把自己实现的程序贴出来,供大家参考。
以后碰到这些问题,可以自己多看看java的API,还是很有帮助的。
    另外在实现ftp上传下载的时候,还要多考虑一下上传下载失败或者网络连接断开的问题,
这需要不同情况不同的处理了,这里不作描述了。
    
    1> 解决乱码的关键
    FtpClient的默认编码格式ISO-8859-1,很多地方都提到了sun.net.NetworkClient类中的encoding属性,
能设置ftp的编码格式,但这个属性是不能直接访问的,可以通过继承FtpClient类的方式来访问;

 

/** *//**
 *
 * <p>Title: FtpOperation.java</p>
 * <p>Description: 为了改变FtpClient的默认编码格式ISO-8859-1为utf-8(或GBK)支持中文,实现了此类继承FtpClient</p>
 * <p>Copyright: Copyright (c) 2009</p>
 * <p>Company: </p>
 * @author
 * @version 1.0
 *
 */
public class CustomFtpClient extends FtpClient {

 private CustomFtpClient() {
  super();
 }
 /** *//**
  * 初始化时必须指定服务器的编码格式
  * @param encodingStr
  */
 protected CustomFtpClient(String encodingStr) {
  super();
  sun.net.NetworkClient.encoding = encodingStr;
 }

 /** *//**
  * 设置连接编码
  * @param encodingStr
  * void
  *
  */
 protected void setEncoding(String encodingStr) {
  sun.net.NetworkClient.encoding = encodingStr;
 }
 /** *//**
  * 取得编码格式
  * @return
  * String
  *
  */
 protected String getEncoding() {
  return sun.net.NetworkClient.encoding ;
 }
}

 

2. 这个类就是ftp上传下载的处理类,主要是注意对连接的处理和一些细节问题,也比较简单,就是要仔细点,这里不啰嗦了。


/** *//**
 *
 * <p>
 * Title: FtpUtils.java
 * </p>
 * <p>
 * Description: FTP相关的操作类,提供ftp登录、ftp上传文件、ftp下载文件等功能<br/>
 * 使用说明:<br/>
 * FtpUtil ftp = new FtpUtil("localhost", "test", "test", "GBK","test", 21); //初始化信息<br/>
 * ftp.connectServer();<br/>
 *    如果需要以ascii格式操作,要调用方法ftp.ftpClient.ascii();<br/>
 * **ftp的相关操作**<br/>
 * ftp.closeConnect();<br/>
 * </p>
 * <p>
 * Copyright: Copyright (c) 2009
 * </p>
 * <p>
 * Company:
 * </p>
 *
 * @author
 * @version 1.0
 *
 */
public class FtpUtil {

    private String serverIp = ""; // 服务器ip

    private String userName = ""; // 登录服务器用户名

    private String password = ""; // 登录服务器密码

    private String path = ""; // 服务器路径

    private int serverPort = -1; // 服务器端口号
   
    private String encoding = "GBK"; //服务器端编码格式

    protected CustomFtpClient ftpClient = null;

    OutputStream os = null;

    FileInputStream is = null;

    /** *//**
     * 构造函数,用配置文件asiainfo.properties中配置的ftp信息进行操作,
     * 需要设置服务器的编码格式PLANDEMO_FTP_ENCODING="GBK"(ftp服务器编码格式)。
     * @param encodingStr
     * @throws Exception
     */
    public FtpUtil() throws Exception {
        try {
            this.serverIp = Configure.getInstance().getProperty(
                    "PLANDEMO_FTP_SERVER"); // 默认服务器
            this.userName = Configure.getInstance().getProperty(
                    "PLANDEMO_FTP_USERNAME"); // 默认用户
            this.password = Configure.getInstance().getProperty(
                    "PLANDEMO_FTP_PASSWORD"); // 默认密码
            this.path = Configure.getInstance().getProperty("PLANDEMO_FTP_DIR"); // 默认路径
            this.encoding = StringUtil.obj2Str(Configure.getInstance().getProperty("PLANDEMO_FTP_ENCODING"),"GBK"); // 默认路径
        } catch (Exception ex) {
            ex.getMessage();
        }
    }

    /** *//**
     * 构造函数 用传入的参数进行ftp操作,必须确定ftp服务器的编码格式
     * @param ip
     *            服务器ip地址
     * @param name
     *            登录服务器用户名
     * @param pwd
     *            登录服务器密码
     * @param encodingStr    ftp服务器的编码格式
     * @param defPath
     *            服务器设置的路径,为空则为默认设置的路径
     * @param port
     *            如果采用服务器默认值设置为-1,其他需要设置
     */
    public FtpUtil(String ip, String name, String pwd, String encodingStr, String defPath, int port) {
        this.serverIp = ip;
        this.userName = name;
        this.password = pwd;
        this.encoding = StringUtil.obj2Str(encodingStr,"GBK");
        this.path = defPath;
        this.serverPort = port;
    }

    /** *//**
     *
     * 连接服务器
     *
     * @return String 如果连接成功返回"true",失败则返回"连接错误或服务器上无此路径!"
     *
     */
    public String connectServer() {
        try {
            ftpClient = new CustomFtpClient(this.encoding);
            if (this.serverPort > 0) {
                ftpClient.openServer(this.serverIp, this.serverPort);
            } else {
                ftpClient.openServer(this.serverIp);
            }

            ftpClient.login(this.userName, this.password);
            if (this.path != null && this.path.trim().length() > 0) {
                ftpClient.cd(this.path);
            }
            ftpClient.binary();
            return "true";
        } catch (Exception ex) {
            ex.printStackTrace();
            return "连接错误或服务器上无此路径!";
        }
    }

    /** *//**
     * 根据传入的文件路径进行连接。
     *
     * @param hostPath
     *            传入的服务器路径
     * @return String 如果连接成功返回"true",没有该路径返回"连接错误或服务器上无此路径!"
     *
     */
    public String connectServer(String hostPath) {
        try {
            ftpClient = new CustomFtpClient(this.encoding);
            if (this.serverPort > 0) {
                ftpClient.openServer(this.serverIp, this.serverPort);
            } else {
                ftpClient.openServer(this.serverIp);
            }
            ftpClient.login(this.userName, this.password);
            if (hostPath != null && hostPath.trim().length() > 0) {
                ftpClient.cd(hostPath);
            }
            ftpClient.binary();
            return "true";
        } catch (Exception ex) {
            ex.printStackTrace();
            return "连接错误或服务器上无此路径!";
        }
    }

    /** *//**
     *
     * 关闭连接 void
     *
     */
    public void closeConnect() {
        try {
            if (is != null) {
                is.close();
            }
            if (os != null) {
                os.close();
            }
            if (ftpClient != null && ftpClient.serverIsOpen()) {
                ftpClient.closeServer();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /** *//**
     *
     * 从ftp下载文件到本地
     *
     * @param filename            服务器上的文件名(与服务器路径的相对路径和文件名)
     * @param newfilename    本地生成的文件名(不带路径会下载到默认的项目的根目录)
     * @return
     * long        下载文件的大小,以字节为单位,下载失败返回-1
     *
     */
    public long downloadFile(String filename, String newfilename) {
        TelnetInputStream is = null;
        FileOutputStream os = null;
        long result =0;
        try {
            is = ftpClient.get(filename);
            java.io.File outfile = new java.io.File(newfilename);
            os = new FileOutputStream(outfile);
            byte[] bytes = new byte[1024];
            int c;
            while ((c = is.read(bytes)) != -1) {
                os.write(bytes, 0, c);
                result += c;
            }
            return result;
        } catch (IOException e) {
            e.printStackTrace();
            return -1;
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /** *//**
     *
     * 获取ftp服务器上的文件大小
     * @param filename
     * @return
     * long        指定文件的大小,以字节为单位,读取文件异常返回-1
     *
     */
    public long getFileSize(String filename) {
        TelnetInputStream is = null;
        long result =0;
        try {
            is = ftpClient.get(filename);
            byte[] bytes = new byte[1024];
            int c;
            while ((c = is.read(bytes)) != -1) {
                result += c;
            }
            return result;
        } catch (IOException e) {
            e.printStackTrace();
            return -1;
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /** *//**
     *
     * ftp上传 如果服务器段已存在名为filename的文件夹,该文件夹中与要上传的文件夹中同名的文件将被替换
     *
     * @param filename
     *            要上传的文件(或文件夹)名
     * @return
     * boolean
     *
     */
    public boolean upload(String filename) {
        String newname = "";
        if (filename.indexOf("/") > -1) {
            newname = filename.substring(filename.lastIndexOf("/") + 1);
        } else if(filename.indexOf("\\") > -1) {
            newname = filename.substring(filename.lastIndexOf("\\") + 1);
        }else {
            newname = filename;
        }
        return upload(filename, newname);
    }

    /** *//**
     *
     * ftp上传 如果服务器段已存在名为newName的文件夹,该文件夹中与要上传的文件夹中同名的文件将被替换
     *
     * @param fileName
     *            要上传的文件(或文件夹)名
     * @param newName
     *            服务器段要生成的文件(或文件夹)名
     * @return
     * boolean
     *
     */
    public boolean upload(String fileName, String newName) {
        try {
            File file_in = new File(fileName);// 打开本地待上传的文件
            if (!file_in.exists()) {
                throw new Exception("此文件或文件夹[" + file_in.getName() + "]有误或不存在!");
            }
            if (file_in.isDirectory()) {
                upload(file_in.getPath(), newName, ftpClient.pwd());
            } else {
                uploadFile(file_in.getPath(), newName);
            }

            if (is != null) {
                is.close();
            }
            if (os != null) {
                os.close();
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("Exception e in Ftp upload(): " + e.toString());
            return false;
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /** *//**
     * 上传文件或者文件夹
     *
     * @param fileName
     * @param newName
     * @param path
     * @throws Exception
     */
    private void upload(String fileName, String newName, String path)
            throws Exception {
        File file_in = new File(fileName);// 打开本地待长传的文件
        if (!file_in.exists()) {
            throw new Exception("此文件或文件夹[" + file_in.getName() + "]有误或不存在!");
        }
        if (file_in.isDirectory()) {
            if (!isDirExist(newName)) {
                createDir(newName);
            }
            ftpClient.cd(newName);
            File sourceFile[] = file_in.listFiles();
            for (int i = 0; i < sourceFile.length; i++) {
                if (!sourceFile[i].exists()) {
                    continue;
                }
                if (sourceFile[i].isDirectory()) {
                    this.upload(sourceFile[i].getPath(), sourceFile[i]
                            .getName(), path + File.separator + newName);
                } else {
                    this.uploadFile(sourceFile[i].getPath(), sourceFile[i]
                            .getName());
                }
            }
        } else {
            uploadFile(file_in.getPath(), newName);
        }
        ftpClient.cd(path);
    }

    /** *//**
     *
     * upload 上传文件
     * @param filename
     *            要上传的文件名
     * @param newname
     *            上传后的新文件名
     * @return
     * @throws Exception
     * long        已经上传文件的大小,异常返回-1
     *
     */
    public long uploadFile(String filename, String newname) throws Exception {
        TelnetOutputStream os = null;
        FileInputStream is = null;
        long result =0;
        try {
            java.io.File file_in = new java.io.File(filename);
            if (!file_in.exists()) {
                return -1;
            }
            os = ftpClient.put(newname);
            is = new FileInputStream(file_in);
            byte[] bytes = new byte[1024];
            int c;
            while ((c = is.read(bytes)) != -1) {
                os.write(bytes, 0, c);
                result += c;
            }
            return result;
        } finally {
            if (is != null) {
                is.close();
            }
            if (os != null) {
                os.close();
            }
        }
    }

    /** *//**
     * 检查文件夹在当前目录下是否存在
     *
     * @param dir
     * @return
     */
    public boolean isDirExist(String dir) {
        String pwd = "";
        try {
            pwd = ftpClient.pwd();
            ftpClient.cd(dir);
            ftpClient.cd(pwd);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /** *//**
     * 在当前目录下创建文件夹
     *
     * @param dir
     * @return
     * @throws Exception
     */
    public boolean createDir(String dir) {
        try {
            ftpClient.ascii();
            StringTokenizer s = new StringTokenizer(dir, File.separator); // sign
            s.countTokens();
            String pathName = ftpClient.pwd();
            while (s.hasMoreElements()) {
                pathName = pathName + File.separator + (String) s.nextElement();
                try {
                    ftpClient.sendServer("MKD " + pathName + "\r\n");
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
                ftpClient.readServerResponse();
            }
            ftpClient.binary();
            return true;
        } catch (IOException e1) {
            e1.printStackTrace();
            return false;
        }
    }

    /** *//**
     *
     * 取得相对于当前连接目录的某个目录下所有文件列表
     *
     * @param subPath
     *            连接目录下的某个子目录开始的路径,如果是连接目录则为空
     * @return List 返回的结果集合,对象类型为文件名称的字符串
     *
     */
    public List<String> getFileList(String subPath) {
        if(subPath==null || subPath.trim().length()<1) {
            return getFileList();
        }
        List<String> list = new ArrayList<String>();
        BufferedReader  dis;
        try {
            dis = new BufferedReader(new InputStreamReader(ftpClient.nameList(subPath),ftpClient.getEncoding()));
            String filename = "";
            while ((filename = dis.readLine()) != null) {
                list.add(filename);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }
    /** *//**
     *
     * 取得相对于当前连接目录的某个目录下所有文件列表
     *
     * @param subPath
     *            连接目录下的某个子目录开始的路径,如果是连接目录则为空
     * @return List 返回的结果集合,对象类型为文件名称的字符串
     *
     */
    public List<String> getFileList() {
        List<String> list = new ArrayList<String>();
        BufferedReader  dis;
        try {
            dis = new BufferedReader(new InputStreamReader(ftpClient.list()));
            String filename = "";
            while ((filename = dis.readLine()) != null) {
                list.add(filename);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }
}

分享到:
评论

相关推荐

    javaftp实现上传下载解决编码问题.doc

    总的来说,Java中实现FTP上传下载并解决编码问题需要理解`FtpClient`的工作原理,以及如何通过自定义类来扩展其功能。同时,编写健壮的FTP工具类时,需要充分考虑异常情况,以确保文件传输的稳定性和可靠性。

    FTP文件上传下载器

    FTP文件上传下载器是一款基于FTP(File Transfer Protocol)协议开发的应用程序,主要功能是实现文件的上传和下载。FTP是一种互联网标准,用于在不同网络之间的计算机之间交换文件。这款工具通常由C#编程语言实现,...

    linux ftp服务器上传文件夹时提示550错误问题解决方法.doc

    Linux FTP 服务器上传文件夹时提示 550 错误问题解决方法是通过解决显示中文的问题和屏蔽原代码中提示错误的对话框来实现的。 相关知识点: 1. Linux 系统不支持中文编码是导致 550 错误的根本原因。 2. 更改 /...

    Domino_java代理实现FTP上传下载

    ### Domino Java 代理实现 FTP 上传下载 #### 知识点概述 在当前的企业级应用环境中,文件传输协议(FTP)依然是一种常见的数据交换方式。本文档主要介绍如何使用 Java 实现与 FTP 服务器的交互功能,具体包括上传...

    pb ftp上传

    4. 可能遇到的问题和解决办法,比如网络问题、权限问题或编码问题等。 5. 安全性和性能优化建议,如使用SSL/TLS加密传输、限制重试次数、错误处理机制等。 通过学习和应用这个解决方案,开发者可以方便地在Power...

    Java实现ftp文件上传下载解决慢中文乱码多个文件下载等问题

    在Java中实现FTP(File Transfer Protocol)文件上传和下载时,可能会遇到各种问题,如速度慢、中文乱码以及多文件下载等。以下将详细解释如何解决这些问题,并提供相关的代码示例。 首先,针对文件上传慢的问题,...

    简单的ftp实现

    FTP协议支持两种传输模式:主动模式(Port)和被动模式(Passive),其中被动模式常用于防火墙或NAT环境,以解决连接问题。 在Linux下实现FTP服务器,我们可以使用开源软件vsftpd(Very Secure FTP Daemon)。安装...

    java ftp 上传 下载 断点续传

    Java FTP(File Transfer Protocol)是Java编程中用于与FTP服务器交互的一种技术,它允许程序员编写应用程序来上传、下载文件,并实现断点续传功能。在本文中,我们将深入探讨Java FTP上传、下载以及断点续传的核心...

    jsp版本ftp文件上传与下载

    本教程将深入讲解如何使用JSP实现FTP文件上传与下载功能,并解决中文文件名的乱码问题。 首先,我们需要理解FTP的基本工作原理。FTP允许用户在客户端和服务器之间交换文件,通常涉及登录、文件传输、目录浏览等操作...

    C#实现的FTP协议的上传、下载

    二、C#中的FTP实现 1. 使用`System.Net.FtpWebRequest`类 C#的标准库`System.Net`包含了一个`FtpWebRequest`类,它是FTP操作的基础。首先,创建一个`FtpWebRequest`实例,设置其方法(如`UploadFile`或`...

    DelphiXe8 FTP客户端程序解决中文乱码问题增加进度条功能

    总结,通过设置FTP会话的字符集、进行编码转换以及利用`TIdFTP`的事件机制,我们可以成功解决Delphi XE8 FTP客户端程序的中文乱码问题并添加进度条功能。这样,用户不仅能正确识别中文文件名,还能清楚地看到文件...

    FTP上传下载客户端

    - 断点续传:某些FTP客户端支持断点续传功能,即使在上传或下载过程中因网络问题中断,也能从上次断开的地方继续,节省时间。 - 跟踪日志:开启日志记录有助于排查连接和传输问题。 - 队列管理:高级FTP客户端...

    文档的上传和下载编码实现

    本项目利用MFC(Microsoft Foundation Classes)框架和SQL数据库技术,实现了对文档(如.txt和.doc格式)的上传和下载功能,下面将详细解释相关知识点。 首先,MFC是微软提供的一个C++库,它封装了Windows API,为...

    FTP上传下载工具

    FTP上传下载工具是实现这一功能的软件应用,它简化了用户与FTP服务器之间的交互过程,使得文件传输变得更为便捷。 FTP协议的工作原理: FTP协议基于TCP/IP协议族,它分为两个通道:命令通道和数据通道。命令通道...

    ftp服务器乱码解决.docx

    例如,当我们在 FTP 客户端上传或下载文件时,中文文件名或路径将被乱码,无法正常地显示和访问。 那么,如何解决这个问题呢?解决方法非常简单。我们只需要修改 Serv-U 的设置,将“对所有已收发的路径和文件名...

    FTP 文件的上传下载

    为了解决这个问题,开发者可能需要确保FTP客户端和服务器之间进行正确的字符编码转换。例如,可以使用`FTPClient`的`setControlEncoding()`方法设置字符编码为UTF-8,以支持中文字符。 此外,考虑到不同的FTP服务器...

    mfc写的ftp上传程序

    FTP支持ASCII和二进制模式,用于处理文本和二进制文件的上传下载。 2. **MFC的网络支持**:MFC提供了CInternetSession、CFtpConnection、CGopherConnection等类,用于处理HTTP、FTP、GOPHER等网络协议。...

    QT的FTP实现例子,支持中文文件

    总结来说,这个项目展示了如何将一个开源的FTP客户端实现从一个开发环境移植到另一个,并解决了中文文件名的支持问题。虽然它缺乏某些高级特性,但作为基础框架,对于学习QT编程和FTP协议的实现非常有价值。对于需要...

    基于Python实现FTP文件上传与下载操作(FTP&SFTP协议)

    **使用`ftplib`实现FTP协议文件上传与下载** 首先,确保已安装`ftplib`库,如果未安装,可以通过`pip install ftplib`命令进行安装。`ftplib`库提供了FTP客户端所需的所有功能,包括连接服务器、登录、上传文件、...

    C语言实现FTP下载文件代码(支持windows和linux和ARM交叉编译)

    本文将深入讲解如何使用C语言实现一个FTP客户端,以实现文件的下载功能,并且该代码支持Windows、Linux操作系统,甚至包括ARM交叉编译环境。 1. FTP基本概念 FTP允许用户在两台计算机之间交换文件,它基于TCP协议,...

Global site tag (gtag.js) - Google Analytics