一、预览(登录根目录下的report下存储)
二、代码
ftp参数
public class TimeFTPconfig {
private Integer id;
private String host;
private Integer port;
private String user;
private String pass;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
}
上传
public static void up(File file,String filename, TimeFTPconfig timeFTPconfig){
FTPClient client = new FTPClient() ;
try {
client.connect(timeFTPconfig.getHost(),timeFTPconfig.getPort()) ;
boolean flag = client.login(timeFTPconfig.getUser(), timeFTPconfig.getPass()) ;
if(flag){
client.setFileType(FTP.BINARY_FILE_TYPE);
//切换工作目录
client.changeWorkingDirectory("/report") ;
InputStream in = new FileInputStream(file) ;
client.storeFile(filename, in) ;
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
下载(由于这里是请求直接下载,所以返回一个输入流,在控制层可以转成输出流进行写出即可)
public static InputStream load(String urlstr, TimeFTPconfig timeFTPconfig){
FTPClient client = new FTPClient() ;
try {
client.connect(timeFTPconfig.getHost(),timeFTPconfig.getPort()) ;
boolean flag = client.login(timeFTPconfig.getUser(), timeFTPconfig.getPass()) ;
if(flag){
/**
* ASCII传输方式 假定用户正在拷贝的文件包含的简单ASCII码文本,
* 如果在远程机器上运行的不是UNIX,当文件传输时ftp通常会自动地调整文件的内容以便于把文件解释成另外那台计算机存储文本文件的格式。
* 但是常常有这样的情况,用户正在传输的文件包含的不是文本文件,它们可能是程序,数据库,字处理文件或者压缩文件,这回导致文件损坏
*/
//设置采用二进制传输方式下载,若采用默认的ascii传输方式下载可能导致文件损失
client.setFileType(FTP.BINARY_FILE_TYPE);
//切换当前目录到xx
client.changeWorkingDirectory("/report") ;
InputStream inputStream=client.retrieveFileStream(urlstr);//根据指定名称获取指定文件
return inputStream;
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
输入流转输出流 (IOUtils这个工具可以直接转化,双流转化不需要File作为媒介)
org.apache.commons.io.IOUtils; 这个包下的
OutputStream os = response.getOutputStream();
IOUtils.copy(FtpClientUtil.load(urlstr,timeFTPconfig), os);
控制层下载
public void downloadFile(){
//查询出ftp的配置
TimeFTPconfig timeFTPconfig = sendReportService.getFtpConfig();
// 打开输出流
try {
HttpServletResponse response=ServletActionContext.getResponse();
// 生成返回流,设置response的类型
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition","attachment;filename*=utf-8'zh_cn'"+URLEncoder.encode(namestr, "UTF-8") );
//response.addHeader("Content-Disposition", "attachment; filename=\"" +namestr+ "\"");
OutputStream os = response.getOutputStream();
IOUtils.copy(FtpClientUtil.load(urlstr,timeFTPconfig), os);
// 关闭流
os.flush();
os.close();
logger.info(SessionUtil.getFromSession(Constants.LOGIN_EMAIL)+"下载已发送附件成功");
} catch (IOException e) {
logger.error(SessionUtil.getFromSession(Constants.LOGIN_EMAIL)+"下载已发送附件失败,原因为:"+e.getMessage());
e.printStackTrace();
}
}
三、知识拓展
1、下载文件会出现中文乱码
response.setHeader("Content-Disposition","attachment;filename*=utf-8'zh_cn'"+URLEncoder.encode(namestr, "UTF-8") );
2、获取ftp的文件
指定文件
InputStream inputStream=client.retrieveFileStream(urlstr); //urlstr 文件名
文件列表
FTPFile[] listFiles = client.listFiles();
3、流不用关闭
OutputStream的close是空实现,不用关闭
os.close(); //空实现
四、ftp假死?
在假死的语句前面加(读写流、获取文件列表前面)
FTPClient.enterLocalPassiveMode()
原因:
FTP有两种模式:主动模式(active mode)和被动模式(passive mode)
默认情况下是启动的主动模式。
两种模式的详细讲解:https://blog.csdn.net/zhangyuan12805/article/details/71425385