`

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

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

    基于FTP协议的数据服务解决方案

    同时, 配合Keepalived (开源的系统高可用解决方案)与LVS实现了高可用、高并发以及良好的拓展性, 在FTP协议之上修改使得服务端支持动态验证、用户隔离并兼容多种编码格式. 在实际的运行中, 以中国科技云iHarbor存储...

    bookwormFTP:Golang FTP 库

    #BookwormFTP ##BookwormFTP 客户端 (github.com/ghepesdoru/bookwormFTP/client) BookwormFTP 客户端是 FTP 客户端,可以作为您应用程序中的快速下载/上传解决方案。 客户端围绕 BookwormFTP 构建块构建,将负责...

    KODExplorer 芒果云-资源管理器

    [关于上传问题] 程序没有做任何限制,如果需要上传大文件,则修改 php.ini:`upload_max_filesize = 1000M post_max_size = 1000M` [关于解压缩问题] 程序不做任何限制,如若失败请设置php内存限制。memory_limit ...

    C#开发典型模块大全(光盘)第一部分

    23.2.1 FTP上传下载技术 23.2.2 XML文件操作 23.2.3 INI文件的读写 23.2.4 动态生成版本面板 23.2.5 使用Hashtable(哈希表)记录版本号及更新信息 23.3 类库设计过程 23.4 服务器端设计过程 23.4.1 服务器端主窗体...

    C#开发典型模块大全(光盘)第二部分

    23.2.1 FTP上传下载技术 23.2.2 XML文件操作 23.2.3 INI文件的读写 23.2.4 动态生成版本面板 23.2.5 使用Hashtable(哈希表)记录版本号及更新信息 23.3 类库设计过程 23.4 服务器端设计过程 23.4.1 服务器端主窗体...

    C#开发典型模块大全

    23.2.1 FTP上传下载技术 610 23.2.2 XML文件操作 611 23.2.3 INI文件的读写 613 23.2.4 动态生成版本面板 614 23.2.5 使用Hashtable(哈希表)记录版本号及更新信息 614 23.3 类库设计过程 615 23.4 ...

    PHP和MySQL Web开发第4版pdf以及源码

    2.4.4 解决打开文件时可能遇到的问题 2.5 写文件 2.5.1 fwrite()的参数 2.5.2 文件格式 2.6 关闭文件 2.7 读文件 2.7.1 以只读模式打开文件:fopen() 2.7.2 知道何时读完文件:feof() 2.7.3 每次读取一行...

    PHP和MySQL WEB开发(第4版)

    2.4.4 解决打开文件时可能遇到的问题 2.5 写文件 2.5.1 fwrite()的参数 2.5.2 文件格式 2.6 关闭文件 2.7 读文件 2.7.1 以只读模式打开文件:fopen() 2.7.2 知道何时读完文件:feof() 2.7.3 每次读取一行数据:fgets...

    PHP和MySQL Web开发第4版

    2.4.4 解决打开文件时可能遇到的问题 2.5 写文件 2.5.1 fwrite()的参数 2.5.2 文件格式 2.6 关闭文件 2.7 读文件 2.7.1 以只读模式打开文件:fopen() 2.7.2 知道何时读完文件:feof() 2.7.3 每次读取一行...

    C#开发典型模块大全(光盘)

    23.2.1 FTP上传下载技术 23.2.2 XML文件操作 23.2.3 INI文件的读写 23.2.4 动态生成版本面板 23.2.5 使用Hashtable(哈希表)记录版本号及更新信息 23.3 类库设计过程 23.4 服务器端设计过程 23.4.1 服务器端主窗体...

    MyFll Microsoft Visual FoxPro设计的扩展库

    MyFll是专为Microsoft Visual FoxPro设计的扩展库,部分函数来自任明汉(RMH myF1论坛)前辈提供的myDll代码翻译而成,由于很多功能利用VFP处理比较烦锁,或无法实现,使用此库可有效解决VFP的弱项。部分与Win32Api...

    PHP程序开发范例宝典III

    让你短时间内由一名菜鸟到高手绝对没问题! 由于权限有限,分3部份下载 PHP程序开发范例宝典 内容提要 《PHP程序开发范例宝典》全面介绍了应用PHP进行网站开发的各种技术和技巧。《PHP程序开发范例宝典》分为20章...

    asp.net知识库

    帮助解决网页和JS文件中的中文编码问题的小工具 慎用const关键字 装箱,拆箱以及反射 动态调用对象的属性和方法——性能和灵活性兼备的方法 消除由try/catch语句带来的warning 微软的应试题完整版(附答案) 一个...

    JAVA上百实例源码以及开源项目

    百度云盘分享 ... Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText();...

    采集工具_采集软件_熊猫智能采集助手

    十、其它采集工具软件常见功能(模拟登录、伪原创、自动运行、多数据库引擎支持、自动发布、FTP同步上传、网页编码自动识别、图片与文件的下载、对采集结果进行过滤挑选、多线程、多任务等等)。 软件同时推出全...

    PHP excel通用成绩查询系统 v7.8 SAE版.zip

    4. 优化选项读取, 用户无需按utf-8编码上传(即下拉不会乱码)。 5. 修正因为打包下载导致的:查询结果 几个字后面空白问题。 PHP excel通用成绩查询系统简介 PHP excel通用成绩查询系统是个极为简单却非常通用、...

    php网络开发完全手册

    15.5 常见问题与解决方案 259 15.6 小结 261 第16章 数据库中的程序逻辑 262 16.1 数据库程序逻辑与PHP程序逻辑的分体 16.1 设计原则 262 16.2 数据库中的程序逻辑与数据的关系 262 16.3 存储过程的设计 263 16.3.1 ...

    熊猫采集助手 v1.1.0 免费版.zip

     十、其它采集工具软件常见功能(模拟登录、伪原创、自动运行、多数据库引擎支持、自动发布、FTP同步上传、网页编码自动识别、图片与文件的下载、对采集结果进行过滤挑选、多线程、多任务等等)。 熊猫采集助手...

    木翼下载系统(MYDOWN) 4.0

    木翼下载系统是为下载型网站提供的解决方案。功能强大,简单易用,生成静态页面,支持Tag, 支持关键词搜索记录,支持可自定义扩展字段, 及其内容设定, 全面满足下载型网站的需求。 木翼下载系统(MYDOWN) 4.0 修正...

Global site tag (gtag.js) - Google Analytics