import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
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 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;
import uk.ltd.getahead.dwr.util.Logger;
public class ApacheFtp
{
private FTPClient ftp=null;
private Logger log=Logger.getLogger(ApacheFtp.class);
/**
* 对象构造 设置将过程中使用到的命令输出到控制台
*/
public ApacheFtp()
{
ftp = new FTPClient();
}
/**
* 用户FTP账号登录
*
* @param url
* FTP地址
* @param port
* FTP端口
* @param username
* 用户名
* @param password
* 密 码
* @return true/false 成功/失败
* @throws SocketException
* @throws IOException
*/
private boolean login(String url, int port, String username, String password) throws SocketException, IOException
{
int reply;
// 1. 连接FTP服务器
// 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
ftp.connect(url, port);
// 2. 设置编码
// 下面三行代码必须要,而且不能改变编码格式,否则不能正确下载中文文件
ftp.setControlEncoding("GBK");
FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
conf.setServerLanguageCode("zh");
// 3. 登录ftp
ftp.login(username, password);
// 看返回的值是不是230,如果是,表示登陆成功
reply = ftp.getReplyCode();
// 以2开头的返回值就会为真
if (!FTPReply.isPositiveCompletion(reply))
{
ftp.disconnect();
log.error(">>>>>>>>>>>>>>>>连接服务器失败!");
return false;
}
return true;
}
/**
* 释放FTP
*/
private void free()
{
if (ftp.isConnected())
{
try
{
// 断开连接
ftp.disconnect();
} catch (IOException e)
{
log.error("FTP断开连接异常:" + e.getMessage());
}
}
}
/**
* FTP文件上传
*
* @param url
* FTP地址
* @param port
* FTP端口
* @param username
* FTP用户名
* @param password
* FTP密码
* @param localAdr
* 上传文件名
* @param remoteAdr
* 指定的FTP目录
* @return
* @throws IOException
*/
public boolean uploadFile(String url, int port, String username, String password, String localAdr, String remoteAdr) throws IOException
{
// 初始表示上传失败
boolean success = false;
/******验证用户登录信息*****/
try{
success = login(url, port, username, password);
if (!success)
{
log.error("FTP用户:"+username+",登录失败!");
return success;
}
} catch (IOException e){
log.error("上传文件异常:" + e.getMessage());
return success;
}
// 设置PassiveMode传输
ftp.enterLocalPassiveMode();
ftp.changeWorkingDirectory(new String(remoteAdr.getBytes("GBK"),"iso-8859-1"));
// 设置FTP文件类型为二进制,如果缺省该句 传输txt正常 但图片和其他格式的文件传输出现乱码
ftp.setFileType(FTP.BINARY_FILE_TYPE);
/*****对远程目录的处理******/
String remoteFileName = remoteAdr;
if (remoteAdr.contains("/"))
{
remoteFileName = remoteAdr.substring(remoteAdr.lastIndexOf("/") + 1);
String directory = remoteAdr.substring(0, remoteAdr.lastIndexOf("/") + 1);
if (!directory.equalsIgnoreCase("/") && !ftp.changeWorkingDirectory(directory))
{
// 如果远程目录不存在,则递归创建远程服务器目录
int start = 0, end = 0;
if (directory.startsWith("/"))
{
start = 1;
} else
{
start = 0;
}
end = directory.indexOf("/", start);
while (true)
{
String subDirectory = remoteAdr.substring(start, end);
if (!ftp.changeWorkingDirectory(subDirectory))
{
if (ftp.makeDirectory(subDirectory))
{
ftp.changeWorkingDirectory(subDirectory);
} else
{
log.error("创建目录失败");
return false;
}
}
start = end + 1;
end = directory.indexOf("/", start);
// 检查所有目录是否创建完毕
if (end <= start)
{
break;
}
}
}
}
/*****执行文件上传******/
InputStream input = null;
try
{
input = new FileInputStream(localAdr);
// 保存文件remoteFileName
success = ftp.storeFile(new String(remoteFileName.getBytes("GBK"), "iso-8859-1") , input);
input.close();
} catch (IOException e)
{
log.error("上传文件失败:" + e.getMessage());
if (input != null)
{
input.close();
}
} finally
{
free();
}
return success;
}
/**
* 删除FTP文件
*
* @param url
* FTP地址
* @param port
* FTP端口
* @param username
* 用户名
* @param password
* 密 码
* @param remoteAdr
* 文件路径
* @param localAdr
* 文件名称
* @return true/false 成功/失败
*/
public boolean deleteFile(String url, int port, String username, String password, String remoteAdr, String localAdr)
{
// localAdr:要上传的文件
// remoteAdr :上传的路径
// 初始表示上传失败
boolean success = false;
try
{
success = login(url, port, username, password);
if (!success)
{
log.error("FTP用户登录:"+username+"失败!");
return success;
}
// 转到指定上传目录
ftp.changeWorkingDirectory(remoteAdr);
FTPFile[] fs = ftp.listFiles(); // 得到目录的相应文件列表
if(fs.length>0)
{
success = ftp.removeDirectory(remoteAdr);
ftp.logout();
}
} catch (IOException e)
{
System.out.println(e.getMessage());
} finally
{
free();
}
return success;
}
/**
* 删除FTP文件和目录
*
* @param url
* FTP地址
* @param port
* FTP端口
* @param username
* 用户名
* @param password
* 密 码
* @param remoteAdr
* 文件路径
* @return true/false 成功/失败
*/
public boolean deleteDir(String url, int port, String username, String password, String remoteAdr)
{
// localAdr:要上传的文件
// remoteAdr :上传的路径
// 初始表示上传失败
boolean success = false;
try
{
success = login(url, port, username, password);
if (!success)
{
log.error("FTP用户登录:"+username+"失败!");
return success;
}
// 转到指定上传目录
ftp.changeWorkingDirectory(remoteAdr);
FTPFile[] fs = ftp.listFiles(); // 得到目录的相应文件列表
if(fs.length>0)
{
success = ftp.removeDirectory(remoteAdr);
ftp.logout();
}
} catch (IOException e)
{
System.out.println(e.getMessage());
} finally
{
free();
}
return success;
}
/**
* 下载FTP文件
*
* @param url
* FPT地址
* @param port
* FTP端口
* @param username
* 用户名
* @param password
* 密 码
* @param remoteremoteAdr
* 远程路径
* @param localAdr
* 文件名称
* @param outputStream文件输出流
* @param response
* Http响应
* @return true/false 成功/失败
*/
public boolean downFile(String url, int port, String username, String password, String remoteremoteAdr, String localAdr, HttpServletResponse response)
{
boolean success = false;
try
{
success = login(url, port, username, password);
if (!success)
{
log.error("FTP用户登录:"+username+"失败!");
return success;
}
// 转移到FTP服务器目录
ftp.changeWorkingDirectory(remoteremoteAdr);
// 得到目录的相应文件列表
FTPFile[] fs = ftp.listFiles();
for (FTPFile ftpFile : fs)
{
if (ftpFile.getName().equals(localAdr))
{
// 这个就就是弹出下载对话框的关键代码
response.setHeader("Content-disposition", "attachment;localAdr=" + URLEncoder.encode(localAdr, "UTF-8"));
// 将文件保存到输出流outputStream中
File f=new File(localAdr);
OutputStream os=new FileOutputStream(f);
ftp.retrieveFile(new String(ftpFile.getName().getBytes("UTF-8"), "ISO-8859-1"), os);
os.flush();
os.close();
}
}
ftp.logout();
success = true;
} catch (IOException e)
{
e.printStackTrace();
} finally
{
free();
}
return success;
}
/**
* 读取FTP文件内容
*
* @param url
* FPT地址
* @param port
* FTP端口
* @param username
* 用户名
* @param password
* 密 码
* @param remoteremoteAdr
* 远程路径
* @param localAdr
* 文件名称
* @return String 文件内容
*/
public String readFileContent(String url, int port, String username, String password, String remoteremoteAdr, String localAdr)
{
String content = null;
try
{
boolean success = login(url, port, username, password);
if (success)
{
// 转移到FTP服务器目录
ftp.changeWorkingDirectory(remoteremoteAdr);
// 得到目录的相应文件列表
FTPFile[] fs = ftp.listFiles();
for (FTPFile ftpFile : fs)
{
if (ftpFile.getName().equals(localAdr))
{
// 这个就就是弹出下载对话框的关键代码
// 将文件保存到输出流outputStream中
File f=new File(localAdr);
ftp.retrieveFile(new String(ftpFile.getName().getBytes("UTF-8"), "ISO-8859-1"), new FileOutputStream(f));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ftp.retrieveFile(ftpFile.getName(), bos);
bos.flush();
bos.close();
content = new String(bos.toByteArray(), "UTF-8");
}
}
}else log.error("FTP用户登录:"+username+"失败!");
} catch (IOException e)
{
System.out.println(e.getMessage());
} finally
{
free();
}
return content;
}
/**
* 判断是否重名的方法
*
* @param localAdr
* 文件名称
* @param fs
* 文件列表数组
* @return
*/
public static boolean isDirExist(String localAdr, FTPFile[] fs)
{
for (FTPFile ftpFile : fs)
{
if (ftpFile.getName().equals(localAdr))
{
return true;
}
}
return false;
}
/**
* 根据重名判断的结果 生成新的文件的名称 更改的重名为 原有名字+[n], n表示数字
*
* @param localAdr
* 文件名称
* @param fs
* FTP文件列表
* @return
*/
public static String changeName(String localAdr, FTPFile[] fs)
{
int n = 0;
// 创建一个可变的字符串对象 即StringBuffer对象,把localAdr值付给该对象
StringBuffer localAdr_ = new StringBuffer("");
localAdr_ = localAdr_.append(localAdr);
// 重名时改名,遍历存在同名的文件
while (isDirExist(localAdr_.toString(), fs))
{
n++;
String a = "[" + n + "]";
// 最后一出现小数点的位置
int b = localAdr_.lastIndexOf(".");
// 最后一次"["出现的位置
int c = localAdr_.lastIndexOf("[");
if (c < 0)
{
c = b;
}
// 文件的名字
StringBuffer name = new StringBuffer(localAdr_.substring(0, c));
// 后缀的名称
StringBuffer suffix = new StringBuffer(localAdr_.substring(b + 1));
localAdr_ = name.append(a).append(".").append(suffix);
}
return localAdr_.toString();
}
}
- 浏览: 27073 次
- 性别:
相关推荐
在实际开发中,还需要考虑安全性问题,例如限制上传文件的类型和大小,防止恶意文件上传;同时,对已上传文件的管理也很重要,包括存储位置、文件命名、权限控制等。 总结一下,Apache文件上传与下载涉及的主要知识...
请注意,实际应用中,您可能还需要处理其他方面,如验证文件类型、重命名上传文件以避免冲突、处理异常、提供反馈给用户等。此外,确保服务器有足够的权限来读写指定的上传目录。 总的来说,Apache Commons ...
2. **PHP配置**:在php.ini文件中,设置`upload_max_filesize`和`post_max_size`以定义允许的最大上传文件大小。 3. **使用Commons-FileUpload库**:Apache Commons FileUpload是Java的一个库,用于处理HTTP多部分/...
Apache Commons FileUpload是Apache软件基金会的一个子项目,它提供了处理HTTP请求中multipart/form-data类型的工具,这是HTML表单上传文件的标准格式。通过这个库,开发者可以轻松地解析请求,获取上传文件的信息...
这个库包含了一些关键类,如`FileItem`表示一个上传文件或表单字段,`FileUpload`负责解析请求并返回`FileItem`对象,以及`DiskFileItemFactory`用于配置存储策略。 `commons-io`是另一个Apache Commons项目,提供...
Apache服务器和后端语言通常都有对上传文件大小的限制。在PHP中,可以通过配置`php.ini`文件中的`upload_max_filesize`和`post_max_size`来设定。在Apache的`httpd.conf`配置文件中,可以使用`LimitRequestBody`指令...
ApacheHTTP服务器的文件上传与下载功能配置.docx
- 检查文件大小:设定上传文件大小的上限,防止DDoS攻击。 - 安全存储:不要将文件保存在可执行路径下,防止直接访问。 - 清理临时文件:上传完成后及时清理临时文件,避免占用空间。 总之,Apache FileUpload为...
Apache文件上传组件工作流程,希望对大家有帮助
2. **文件命名**:处理上传文件时,应避免使用用户提供的文件名,以防路径遍历攻击。 3. **异常处理**:捕获并处理解析和保存文件过程中可能抛出的异常。 **最佳实践:** 1. 使用最新的库版本,以获得最新的安全...
为了模拟HTML表单上传文件,我们需要使用`MultipartEntityBuilder`来构建一个多部分实体,它允许我们混合文本字段和二进制数据,如文件。以下是一些关键步骤: 1. **依赖引入**:首先,确保在项目中引入Apache ...
本篇文章将深入探讨如何使用Apache Commons FileUpload库来创建一个带有进度条的文件上传功能。 首先,我们需要在项目中引入Apache Commons FileUpload库。通常,我们会通过Maven或Gradle将其作为依赖添加到构建...
标题“org.apache 文件上传”指的是使用Apache开源组织提供的文件上传组件进行操作的场景。Apache Commons FileUpload库是Java中常用的一个处理HTTP请求中文件上传的工具包,它使得开发者能够轻松地从表单中接收多个...
使用本程序时,注意上传端的参数设置,文件路径在前,文件附件在后,一次上传一个文件 StringPart filePathPart = new StringPart("filePath", "111/"+targetFile.getName(), "utf-8"); FilePart part = new ...
3. **解析请求**:使用`parseRequest()`方法解析请求,获取`List<Part>`对象,每个`Part`代表一个上传文件。 4. **处理文件**:遍历`Part`列表,对每个文件进行处理,如保存到服务器、验证大小等。 ### 流式...
上传文件" name="submit"> ``` 当用户提交表单后,Servlet将被调用。在Servlet中,我们需要解析`multipart/form-data`格式的请求。由于不使用Apache的FileUpload库,我们需要手动解析请求。可以使用`...
在描述中提到了与JSP SmartUpload的比较,SmartUpload也是一个广泛使用的文件上传库,但Apache上传组件可能提供了类似的特性,并且在某些方面可能具有更好的性能或易用性。 Apache上传组件的核心功能包括: 1. **...
以下是一些使用Apache Commons FileUpload和Commons IO进行文件上传的关键步骤: 1. 引入依赖:首先在项目中引入Apache Commons FileUpload和Commons IO的JAR包,如果是Maven项目,可以在pom.xml文件中添加对应的...