jxwpzudcdn 发表于 2016-6-9 10:41:51

ftp文件上传下载工具类及用法

  弄了一天的ftp文件上传下载,最棘手的有两个问题:
  1、上传中文文件在ftp服务器(linux)上的乱码问题;
  2、总是提示这个错误:java.net.SocketException: Software caused connection abort: recv failed
  
  对于第二个问题大家可以上网找找,大部分说的是出现这个问题的原因,并没有说怎么解决。也希望哪位大神留言帮忙解决那是感激不尽啊!
  
  我的实现方法就是:不把自己撞在南墙上,换一条道走,诶!两个问题都解决了!(附件是必须的jar包)
  这个工具类总结了网上很多种方法,只需要引入一个jar包,不像其他的demo需要2--3个jar包。个人觉得还是很方便的。
  
  工具类代码如下:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.net.URLEncoder;
import java.util.Properties;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
/**
* CopyRright (c)2012-2013:   
* Project:nankai                                       
* Module ID: FTPUtils
* Comments:                                             
* JDK version used:      JDK1.7                              
* Author:                     
* Create Date:2013-9-18
* Modified By:                                          
* Modified Date:                                    
* Why & What is modified      
* Version: 1.0                     
*/
public class FTPUtils {
//读取配置文件中的系统ip和port
private static Properties p = new PropertiesLoader("classpath:/application.development.properties", "classpath:/application.properties")
.getProperties();
private static String ftpIp = p.getProperty("ftp.ip"); // 服务器ip
private static int ftpPort = Integer.parseInt(p.getProperty("ftp.port")); // 服务器端口号
private static String userName = p.getProperty("ftp.username"); // 登录服务器用户名
private static String password = p.getProperty("ftp.password"); // 登录服务器密码
//    protected CustomFtpClient ftpClient = null;
//    OutputStream os = null;
//    FileInputStream is = null;
/**
* Description: 向FTP服务器上传文件
*
* @param path
*            FTP服务器保存目录
* @param filename
*            上传到FTP服务器上的文件名
* @param input
*            输入流
* @return 成功返回true,否则返回false
* @throws IOException
* @throws SocketException
*/
public static boolean uploadFile(String path, String filename, InputStream input) throws SocketException, IOException {
boolean success = false;
FTPClient ftp = new FTPClient();
ftp.connect(ftpIp, ftpPort);// 连接FTP服务器
int reply;
// 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
ftp.login(userName, password);// 登录
// 设置PassiveMode传输
ftp.enterLocalPassiveMode();
// 设置以二进制流的方式传输
ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
ftp.setFileType(FTP.BINARY_FILE_TYPE);
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return success;
}
String filename1 = new String(filename.getBytes("GBK"), "ISO-8859-1");
String path1 = new String(path.getBytes("GBK"), "ISO-8859-1");
boolean isChangeWork = ftp.changeWorkingDirectory(path1);
if (!isChangeWork) {
boolean isMade = ftp.makeDirectory(path1);
if (!isMade) {
throw new IOException("ftp上传文件创建目录失败");
}
isChangeWork = ftp.changeWorkingDirectory(path1);
}
ftp.storeFile(filename1, input);
ftp.logout();
success = true;
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
return success;
}
/**
* Description: 从FTP服务器下载文件
*
* @param remotePath
*            FTP服务器上的相对路径
* @param fileName
*            要下载的文件名
* @param localPath
*            下载后保存到本地的路径
* @return
* @throws IOException
* @throws SocketException
*/
public static boolean downloadFile(String path, String fileName, OutputStream outputStream) throws SocketException, IOException {
boolean success = false;
FTPClient ftp = new FTPClient();
ftp.connect(ftpIp, ftpPort);// 连接FTP服务器
int reply;
// 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
ftp.login(userName, password);// 登录
// 设置PassiveMode传输
ftp.enterLocalPassiveMode();
// 设置以二进制流的方式传输
ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
ftp.setFileType(FTP.BINARY_FILE_TYPE);
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
}
String filename1 = new String(fileName.getBytes("GBK"), "ISO-8859-1");
String path1 = new String(path.getBytes("GBK"), "ISO-8859-1");
boolean isChangeWork = ftp.changeWorkingDirectory(path1);
if (!isChangeWork) {
throw new IOException("ftp目录不存在");
}
InputStream input = ftp.retrieveFileStream(filename1);
int buf = -1;
while ((buf = input.read()) != -1) {
outputStream.write(buf);
}
outputStream.flush();
input.close();
ftp.logout();
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
return success;
}
}
  
  使用方法:
  上传直接通过FTPUtils.uploadFile(ftpPath, materialName, input);就可以
  下载(以springmvc为例子):

@RequestMapping("download")
public void download(HttpServletResponse response, String materialName, Model model) throws IOException {
response.setContentType("application/x-download");
//给用户提供的下载文件名,处理乱码问题
String filedisplay = URLEncoder.encode(materialName, "UTF-8");
response.addHeader("Content-Disposition", "attachment;filename=" + filedisplay);
OutputStream outputStream = response.getOutputStream();
String remotePath = "/material/2013/";
FTPUtils.downloadFile(remotePath, materialName, outputStream);
}
  会将文件下载到本地。
  注意:在设置Content-Disposition头字段之前,一定要设置Content-Type头字段。当Content-Type 的类型为要下载的类型时 , 这个信息头会告诉浏览器这个文件的名字和类型。
  
  最后,希望大家有谁发现这里有不合适或者需要改进的地方,请留言与我联系,共享万岁!
页: [1]
查看完整版本: ftp文件上传下载工具类及用法