这一期,我们来学习一下如何用Java连接FTP服务器。在工程项目中,我们往往需要连接FTP服务器。当我们有此需求时,可以从两个方面考虑。第一,根据FTP协议自己写出一套程序,这是一种思路,当然这是一件很费时又耗成本的一件事。我们是工程师,我们的目的是把需求实现,而不是科研项目。所以得考虑另一种思路,去寻找已经做好的API。好巧,刚好有一个开源组织为我们做好了这个API,那就是伟大的Apache。下面就开始时根据Apache给我们提供的API完成我们的需求。
第一步,下载jar包,登录官网如下:
然后找到“Projects”点进去,出现下拉框。点击“Project List”
找到Commons点进去
往下滑,找到“net”
点进去,然后在左上角找到“download”
点击然后往下滑,找到如图
其中Binaries是编译后的jar,Source是源代码。一般使用的是编译后的jar,将其下载,下载之后就是新建项目导jar包。如何导jar,不会再这里说。此时,我们jar已经准备好。我们还需要一个ftp服务器,如何建立ftp服务器也不会再这里说。现在假设你已经创建好项目,已经建立好ftp服务器,下面就直接上代码了。
package my;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
public class TestFTPClient
{
// API里对中文FTP目录的处理有点问题
// 在调用 changeWorkingDirectory() / listFiles()等方法时,将参数路径转换一下
public static String ftpPath(String path)
{
try
{
return new String(path.getBytes("UTF-8"), FTP.DEFAULT_CONTROL_ENCODING);
} catch (UnsupportedEncodingException e)
{
return "";
}
}
public static void main(String[] args) throws Exception
{
FTPClient ftp = new FTPClient();
// 连接服务器
ftp.connect("127.0.0.1", 21);
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply))
{
ftp.disconnect();
System.out.println("** 无法连接至FTP服务器!");
System.exit(1);
}
if (!ftp.login("test", "123456"))
{
ftp.logout();
System.out.println("** 错误的用户名或密码!");
System.exit(1);
}
System.out.println("Connected.");
// 字节传输 BINARY_FILE_TYPE
// 文本传输 ASCII_FILE_TYPE
// 一般使用BINARY模式来传输文件,很少使用 ASCII_FILE_TYPE
ftp.setFileType(FTP.BINARY_FILE_TYPE);
// 主动模式: enterLocalActiveMode()
// 被动模式: enterLocalPassiveMode()
// 一般选择被动模式
ftp.enterLocalPassiveMode();
// 设置控制通道的字符集, 要与服务端的设定一致
ftp.setControlEncoding("UTF-8");
// 切换目录 ( 用ftpPath() 转换一下 )
// boolean rc = ftp.changeWorkingDirectory(ftpPath("/图片"));
// if(!rc)
// {
// System.out.println("切换目录出错!");
// }
// ...
//
// 列出所有的文件/子目录
// listFile(ftp);
//上传一个文件
//upload(ftp);
// 下载一个文件
download(ftp);
ftp.logout();
ftp.disconnect();
System.out.println("Quit.");
}
public static void listFile(FTPClient ftp)
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("> list");
FTPFile[] ftpFiles;
try
{
ftpFiles = ftp.listFiles();
for (FTPFile f : ftpFiles)
{
String time = sdf.format(f.getTimestamp().getTime());
String info = "";
if (f.isDirectory())
info = String.format("+ %-20s", f.getName());
else
info = String.format(" %-20s %8d %s", f.getName(), f.getSize(), time);
System.out.println(info);
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 上传一个文件
public static void upload(FTPClient ftp)
{
File localFile = new File("E:\\代码\\HBiuder.zip");
InputStream inStream;
OutputStream outStream;
try
{
String remotePath = ftpPath(localFile.getName());
inStream = new FileInputStream(localFile);
//
// 小文件直接 用
// ftp.storeFile(remotePath, inStream);
//大文件时用这个方法
outStream = ftp.storeFileStream(remotePath);
// 大文件,可以自己掌握进度
byte[] buffer = new byte[4000];
while (true)
{
int n = inStream.read(buffer);
if (n <= 0)
break;
outStream.write(buffer, 0, n);
}
inStream.close();
outStream.close();
} catch (FileNotFoundException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//文件下载
public static void download(FTPClient ftp) throws Exception
{
File localFile = new File("D:/tmp/copy.zip");
localFile.getParentFile().mkdirs();
//
String remotePath = ftpPath("/HBiuder.zip");
OutputStream outStream = new FileOutputStream(localFile);
// 小文件直接 用
// ftp.retrieveFile(remotePath, outStream);
// 大文件,可以自己掌握进度
InputStream inStream = ftp.retrieveFileStream(remotePath);
if(inStream == null)
throw new Exception("远程文件不存在!" + remotePath);
byte[] buffer = new byte[4000];
while(true)
{
int n =inStream.read(buffer);
if(n <= 0) break;
outStream.write(buffer,0,n);
}
inStream.close();
outStream.close();
}
}
仅供参考,如有不足,多多指教。