您的位置:首页 > 编程语言 > Java开发

JAVA 实现FTP上传下载(sun.net.ftp.FtpClient)

2017-01-06 10:40 423 查看
package com.why.ftp;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import sun.net.TelnetInputStream;
import sun.net.TelnetOutputStream;
import sun.net.ftp.FtpClient;

/**
* ftp上传,下载
* @author why 2009-07-30
*
*/
public class FtpUtil {

private String ip = "";

private String username = "";

private String password = "";

private int port = -1;

private String path = "";

FtpClient ftpClient = null;

OutputStream os = null;

FileInputStream is = null;

public FtpUtil(String serverIP, String username, String password) {
this.ip = serverIP;
this.username = username;
this.password = password;
}

public FtpUtil(String serverIP, int port, String username, String password) {
this.ip = serverIP;
this.username = username;
this.password = password;
this.port = port;
}

/**
* 连接ftp服务器
*
* @throws IOException
*/
public boolean connectServer(){
ftpClient = new FtpClient();
try {
if(this.port != -1){
ftpClient.openServer(this.ip,this.port);
}else{
ftpClient.openServer(this.ip);
}
ftpClient.login(this.username, this.password);
if (this.path.length() != 0){
ftpClient.cd(this.path);// path是ftp服务下主目录的子目录
}
ftpClient.binary();// 用2进制上传、下载
System.out.println("已登录到\"" + ftpClient.pwd() + "\"目录");
return true;
}catch (IOException e){
e.printStackTrace();
return false;
}
}

/**
* 断开与ftp服务器连接
*
* @throws IOException
*/
public boolean closeServer(){
try{
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
if (ftpClient != null) {
ftpClient.closeServer();
}
System.out.println("已从服务器断开");
return true;
}catch(IOException e){
e.printStackTrace();
return false;
}
}

/**
* 检查文件夹在当前目录下是否存在
* @param dir
* @return
*/
private 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
*/
private boolean createDir(String dir){
try{
ftpClient.ascii();
StringTokenizer s = new StringTokenizer(dir, "/"); //sign
s.countTokens();
String pathName = ftpClient.pwd();
while(s.hasMoreElements()){
pathName = pathName + "/" + (String) s.nextElement();
try {
ftpClient.sendServer("MKD " + pathName + "\r\n");
} catch (Exception e) {
e = null;
return false;
}
ftpClient.readServerResponse();
}
ftpClient.binary();
return true;
}catch (IOException e1){
e1.printStackTrace();
return false;
}
}

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

/**
* ftp上传
* 如果服务器段已存在名为newName的文件夹,该文件夹中与要上传的文件夹中同名的文件将被替换
*
* @param fileName 要上传的文件(或文件夹)名
* @param newName 服务器段要生成的文件(或文件夹)名
* @return
*/
public boolean upload(String fileName, String newName){
try{
String savefilename = new String(fileName.getBytes("ISO-8859-1"), "GBK");
File file_in = new File(savefilename);//打开本地待长传的文件
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{
String savefilename = new String(fileName.getBytes("ISO-8859-1"), "GBK");
File file_in = new File(savefilename);//打开本地待长传的文件
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+"/"+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 -1 文件不存在 >=0 成功上传,返回文件的大小
* @throws Exception
*/
public long uploadFile(String filename, String newname) throws Exception{
long result = 0;
TelnetOutputStream os = null;
FileInputStream is = null;
try {
java.io.File file_in = new java.io.File(filename);
if(!file_in.exists())
return -1;
os = ftpClient.put(newname);
result = file_in.length();
is = new FileInputStream(file_in);
byte[] bytes = new byte[1024];
int c;
while((c = is.read(bytes)) != -1){
os.write(bytes, 0, c);
}
}finally{
if(is != null){
is.close();
}
if(os != null){
os.close();
}
}
return result;
}

/**
* 从ftp下载文件到本地
*
* @param filename 服务器上的文件名
* @param newfilename 本地生成的文件名
* @return
* @throws Exception
*/
public long downloadFile(String filename, String newfilename){
long result = 0;
TelnetInputStream is = null;
FileOutputStream os = null;
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 = result + c;
}
}catch (IOException e){
e.printStackTrace();
}finally{
try {
if(is != null){
is.close();
}
if(os != null){
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}

/**
* 取得相对于当前连接目录的某个目录下所有文件列表
*
* @param path
* @return
*/
public List getFileList(String path){
List list = new ArrayList();
DataInputStream dis;
try {
dis = new DataInputStream(ftpClient.nameList(this.path + path));
String filename = "";
while((filename = dis.readLine()) != null){
list.add(filename);
}
} catch (IOException e) {
e.printStackTrace();
}
return list;
}

public static void main(String[] args){
FtpUtil ftp = new FtpUtil("133.224.202.2","tstbill","tstbill");
ftp.connectServer();
boolean result = ftp.upload("C:/test_why", "test_why/test");
System.out.println(result?"上传成功!":"上传失败!");
List list = ftp.getFileList("test_why/test");
for(int i=0;i<list.size();i++){
String name = list.get(i).toString();
System.out.println(name);
}
ftp.closeServer();
/**
FTP远程命令列表
USER    PORT    RETR    ALLO    DELE    SITE    XMKD    CDUP    FEAT
PASS    PASV    STOR    REST    CWD     STAT    RMD     XCUP    OPTS
ACCT    TYPE    APPE    RNFR    XCWD    HELP    XRMD    STOU    AUTH
REIN    STRU    SMNT    RNTO    LIST    NOOP    PWD     SIZE    PBSZ
QUIT    MODE    SYST    ABOR    NLST    MKD     XPWD    MDTM    PROT
在服务器上执行命令,如果用sendServer来执行远程命令(不能执行本地FTP命令)的话,所有FTP命令都要加上\r\n
ftpclient.sendServer("XMKD /test/bb\r\n"); //执行服务器上的FTP命令
ftpclient.readServerResponse一定要在sendServer后调用
nameList("/test")获取指目录下的文件列表
XMKD建立目录,当目录存在的情况下再次创建目录时报错
XRMD删除目录
DELE删除文件
*/
}

}

下面是FtpClient类的一些介绍:

sun.net.ftp.FtpClient.,该类库主要提供了用于建立FTP连接的类。利用这些类的方法,编程人员可以远程登录到FTP服务器,列举该服务器上的目录,设置传输协议,以及传送文件。FtpClient类涵盖了几乎所有FTP的功能,FtpClient的实例变量保存了有关建立"代理"的各种信息。下面给出了这些实例变量:

  public static boolean useFtpProxy
  这个变量用于表明FTP传输过程中是否使用了一个代理,因此,它实际上是一个标记,此标记若为TRUE,表明使用了一个代理主机。

  public static String ftpProxyHost
  此变量只有在变量useFtpProxy为TRUE时才有效,用于保存代理主机名。

  public static int ftpProxyPort
  此变量只有在变量useFtpProxy为TRUE时才有效,用于保存代理主机的端口地址。

  FtpClient有三种不同形式的构造函数,如下所示:

  1、public FtpClient(String hostname,int port)
   此构造函数利用给出的主机名和端口号建立一条FTP连接。

  2、public FtpClient(String hostname)
  此构造函数利用给出的主机名建立一条FTP连接,使用默认端口号。

  3、FtpClient()
  此构造函数将创建一FtpClient类,但不建立FTP连接。这时,FTP连接可以用openServer方法建立。

  一旦建立了类FtpClient,就可以用这个类的方法来打开与FTP服务器的连接。类ftpClient提供了如下两个可用于打开与FTP服务器之间的连接的方法。

  public void openServer(String hostname)
  这个方法用于建立一条与指定主机上的FTP服务器的连接,使用默认端口号。

  public void openServer(String host,int port)
  这个方法用于建立一条与指定主机、指定端口上的FTP服务器的连接。

  打开连接之后,接下来的工作是注册到FTP服务器。这时需要利用下面的方法。

  public void login(String username,String password)
  此方法利用参数username和password登录到FTP服务器。使用过Intemet的用户应该知道,匿名FTP服务器的登录用户名为anonymous,密码一般用自己的电子邮件地址。

  下面是FtpClient类所提供的一些控制命令。

  public void cd(String remoteDirectory):该命令用于把远程系统上的目录切换到参数remoteDirectory所指定的目录。
  public void cdUp():该命令用于把远程系统上的目录切换到上一级目录。
  public String pwd():该命令可显示远程系统上的目录状态。
  public void binary():该命令可把传输格式设置为二进制格式。
  public void ascii():该命令可把传输协议设置为ASCII码格式。
  public void rename(String string,String string1):该命令可对远程系统上的目录或者文件进行重命名操作。

  除了上述方法外,类FtpClient还提供了可用于传递并检索目录清单和文件的若干方法。这些方法返回的是可供读或写的输入、输出流。下面是其中一些主要的方法。

  public TelnetInputStream list()
  返回与远程机器上当前目录相对应的输入流。

  public TelnetInputStream get(String filename)
  获取远程机器上的文件filename,借助TelnetInputStream把该文件传送到本地。

  public TelnetOutputStream put(String filename)
  以写方式打开一输出流,通过这一输出流把文件filename传送到远程计算机


使用sun.net.ftp.FtpClient进行上传功能开发,在jdk1.7上不适用问题的解决

标签: java上传
2013-07-14 19:05 20754人阅读 评论(3) 收藏 举报

本文章已收录于:

.embody { padding: 10px 10px 10px; margin: 0 -20px; border-bottom: solid 1px #ededed }
.embody_b { margin: 0; padding: 10px 0 }
.embody .embody_t,.embody .embody_c { display: inline-block; margin-right: 10px }
.embody_t { font-size: 12px; color: #999 }
.embody_c { font-size: 12px }
.embody_c img,.embody_c em { display: inline-block; vertical-align: middle }
.embody_c img { width: 30px; height: 30px }
.embody_c em { margin: 0 20px 0 10px; color: #333; font-style: normal }

版权声明:本文为博主原创文章,未经博主允许不得转载。

之前项目上开发了一个上传文件的功能,使用的是sun.net.ftp.FtpClient这个类

连接服务器的代码大概如下:

public static FtpClient ftpClient = null;

ftpClient = new FtpClient();
ftpClient.openServer(server);
ftpClient.login(user, password);

之前这个功能是在jdk1.6基础上进行开发的。使用一切正常。

但是因为客户的环境上已经有了jdk1.7的环境,所以直接进行部署,发现文件上传失败,并且报如下错误:

cannont instantiate the type FtpClient

经过调查,发现

1) sun.net.ftp.FtpClient 这个类在jdk的帮助文档中没有具体的说明,也就是并没有对外公开。并且这个类是在jdk的 rt.jar中实现的。

2)jdk1.7下其构造函数FtpClient()被定义为private类型,所以无法new了。 在jdk1.7,已经换成了 FtpClient.create(ip)方法

同时,其他的一些方法也基本都改掉了,

如 ftpClient.openServer(server);
ftpClient.login(user, password);

就可以换成:ftpClient.login(user, null, password);

ftpClient.binary(); ---> ftpClient.setBinaryType();

ftpClient.put(remotefilename);--->ftpClient.putFileStream(remotefilename, true);

等。

如果这样的话,解决这个问题有2个办法:

1. 重写这个上传功能, 但是1.6版本怎么办呢, 可能需要根据jdk版本进行分开处理

2. 在 既存的服务器上,构筑1.6的环境,然后 tomcat 启动的时候,加载1.6的jdk。

这个在linux或者windows上都非常方便。 如果windowss上,tomcat是以服务形式启动的话,直接修改,关联的java 虚拟机源就可以了。

1.package com.boonya.upload.util.simple;
2.
3.import java.io.File;
4.import java.io.FileInputStream;
5.import java.io.FileOutputStream;
6.import java.io.IOException;
7.import java.net.InetSocketAddress;
8.import sun.net.TelnetInputStream;
9.import sun.net.TelnetOutputStream;
10.import sun.net.ftp.FtpClient;
11.import sun.net.ftp.FtpProtocolException;
12./**
13. * Java自带的API对FTP的操作
14. * @Jdk:version 1.7
15. * @Title:Ftp.java
16. * @author: boonya
17. * @notice: 貌似此方法有个缺陷,不能操作大文件
18. */
19.public class FtpJdk
20.{
21.    /**
22.     *
23.     * 本地文件名
24.     */
25.    private String localfilename;
26.    /**
27.     *
28.     * 远程文件名
29.     */
30.    private String remotefilename;
31.    /**
32.     *
33.     * FTP客户端
34.     */
35.    private FtpClient ftpClient;
36.
37.    /**
38.     * 服务器连接
39.     *
40.     * @param ip
41.     *            服务器IP
42.     * @param port
43.     *            服务器端口
44.     * @param user
45.     *            用户名
46.     * @param password
47.     *            密码
48.     * @param path
49.     *            服务器路径
50.     * @throws FtpProtocolException
51.     *
52.     */
53.    public void connectServer(String ip, int port, String user, String password, String path) throws FtpProtocolException
54.    {
55.        try
56.        {
57.            /* ******连接服务器的两种方法****** */
58.            // 第一种方法
59.            /*
60.             * ftpClient =FtpClient.create();
61.             * ftpClient.connect(new InetSocketAddress(ip, port));
62.             */
63.            // 第二种方法
64.            ftpClient = FtpClient.create(ip);
65.            ftpClient.login(user, null, password);
66.            // 设置成2进制传输
67.            ftpClient.setBinaryType();
68.            System.out.println("login success!");
69.
70.            if (path.length() != 0)
71.            {
72.                // 把远程系统上的目录切换到参数path所指定的目录
73.                ftpClient.changeDirectory(path);
74.            }
75.            ftpClient.setBinaryType();
76.        } catch (IOException ex)
77.        {
78.            ex.printStackTrace();
79.            throw new RuntimeException(ex);
80.        }
81.
82.    }
83.
84.    /**
85.     * 关闭连接
86.     *
87.     */
88.
89.    public void closeConnect()
90.    {
91.        try
92.        {
93.            ftpClient.close();
94.            System.out.println("disconnect success");
95.        } catch (IOException ex)
96.        {
97.            System.out.println("not disconnect");
98.            ex.printStackTrace();
99.            throw new RuntimeException(ex);
100.        }
101.    }
102.
103.    /**
104.     *
105.     * 上传文件
106.     *
107.     * @param localFile
108.     *            本地文件
109.     * @param remoteFile
110.     *            远程文件
111.     * @throws FtpProtocolException
112.     */
113.    public void upload(String localFile, String remoteFile) throws FtpProtocolException
114.    {
115.        this.localfilename = localFile;
116.        this.remotefilename = remoteFile;
117.        TelnetOutputStream os = null;
118.        FileInputStream is = null;
119.        try
120.        {
121.            // 将远程文件加入输出流中
122.            os = (TelnetOutputStream) ftpClient.putFileStream(this.remotefilename, true);
123.
124.            // 获取本地文件的输入流
125.            File file_in = new File(this.localfilename);
126.            is = new FileInputStream(file_in);
127.
128.            // 创建一个缓冲区
129.            byte[] bytes = new byte[1024];
130.            int c;
131.            while ((c = is.read(bytes)) != -1)
132.            {
133.                os.write(bytes, 0, c);
134.            }
135.            System.out.println("upload success");
136.        } catch (IOException ex)
137.        {
138.            System.out.println("not upload");
139.            ex.printStackTrace();
140.            throw new RuntimeException(ex);
141.        } finally
142.        {
143.            try
144.            {
145.                if (is != null)
146.                {
147.                    is.close();
148.                }
149.            } catch (IOException e)
150.            {
151.                e.printStackTrace();
152.            } finally
153.            {
154.                try
155.                {
156.                    if (os != null)
157.                    {
158.                        os.close();
159.                    }
160.                } catch (IOException e)
161.                {
162.                    e.printStackTrace();
163.                }
164.            }
165.        }
166.    }
167.
168.    /**
169.     *
170.     * 下载文件
171.     *
172.     * @param remoteFile
173.     *            远程文件路径(服务器端)
174.     * @param localFile
175.     *            本地文件路径(客户端)
176.     * @throws FtpProtocolException
177.     *
178.     */
179.    public void download(String remoteFile, String localFile) throws FtpProtocolException
180.    {
181.        TelnetInputStream is = null;
182.        FileOutputStream os = null;
183.        try
184.        {
185.
186.            // 获取远程机器上的文件filename,借助TelnetInputStream把该文件传送到本地。
187.            is = (TelnetInputStream) ftpClient.getFileStream(remoteFile);
188.            File file_in = new File(localFile);
189.            os = new FileOutputStream(file_in);
190.
191.            byte[] bytes = new byte[1024];
192.            int c;
193.            while ((c = is.read(bytes)) != -1)
194.            {
195.                os.write(bytes, 0, c);
196.            }
197.            System.out.println("download success");
198.        } catch (IOException ex)
199.        {
200.            System.out.println("not download");
201.            ex.printStackTrace();
202.            throw new RuntimeException(ex);
203.        } finally
204.        {
205.            try
206.            {
207.                if (is != null)
208.                {
209.                    is.close();
210.                }
211.            } catch (IOException e)
212.            {
213.                e.printStackTrace();
214.            } finally
215.            {
216.                try
217.                {
218.                    if (os != null)
219.                    {
220.                        os.close();
221.                    }
222.                } catch (IOException e)
223.                {
224.                    e.printStackTrace();
225.                }
226.            }
227.        }
228.    }
229.
230.    /**
231.     * 函数入口
232.     *
233.     * @param agrs
234.     */
235.    public static void main(String agrs[])
236.    {
237.
238.        String filepath[] =
239.        { "/temp/aa.txt", "/temp/regist.log" };
240.        String localfilepath[] =
241.        { "C:\\tmp\\1.txt", "C:\\tmp\\2.log" };
242.        FtpJdk ftp = new FtpJdk();
243.        /*
244.         * 使用默认的端口号、用户名、密码以及根目录连接FTP服务器
245.         */
246.        try
247.        {
248.            ftp.connectServer("127.0.0.1", 22, "boonya", "user@", "/temp");
249.        } catch (FtpProtocolException e)
250.        {
251.            e.printStackTrace();
252.        }
253.        // 下载
254.        for (int i = 0; i < filepath.length; i++)
255.        {
256.            try
257.            {
258.                ftp.download(filepath[i], localfilepath[i]);
259.            } catch (FtpProtocolException e)
260.            {
261.                e.printStackTrace();
262.            }
263.        }
264.        String localfile = "E:\\contact.txt";
265.        String remotefile = "/temp/records.txt";
266.        // 上传
267.        try
268.        {
269.            ftp.upload(localfile, remotefile);
270.        } catch (FtpProtocolException e)
271.        {
272.            e.printStackTrace();
273.        }
274.        ftp.closeConnect();
275.    }
276.
277.}


Java实现FTP上传下载文件的工具包有很多,这里我采用Java自带的API,实现FTP上传下载文件。另外JDK1.7以前的版本与其之后版本的API有了较大的改变了。

例如:

JDK1.7之前JDK1.7
ftpClient = new FtpClinet()ftpClient = FtpClient.create(ip)
ftpclient.login(user,password)ftpclient.login(user,null,password)
ftpclient.binary()ftpClient.setBinaryType();
一. 连接FTP服务器





































































二. 上传文件

















































































三. 下载文件

































































































四. 遍历FTP目录文件


































































                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: