1.获取连接
private static FTPClient getConnect(String chilPath) { FTPClient connect = new FTPClient(); try { connect.connect(AppConfig.getProperty("fp_host"), Integer.valueOf(AppConfig.getProperty("fp_port"))); connect.login(AppConfig.getProperty("fp_username"), AppConfig.getProperty("fp_password")); connect.setFileType(FTPClient.BINARY_FILE_TYPE); if (!FTPReply.isPositiveCompletion(connect.getReplyCode())) { connect.disconnect(); } if (StringUtils.isEmpty(chilPath)) { connect.changeWorkingDirectory("/"); } else { // 建立新的文件夹,FTP使用ISO8859-1编码方式 String tempPath = new String((chilPath).getBytes("UTF-8"), "ISO-8859-1"); connect.makeDirectory(tempPath); connect.changeWorkingDirectory(tempPath); } } catch (Exception e) { } return connect; }
2.调用连接,下载文件(如果有父级结构)
/** * 下载文件 有子文件夹 * * @param fileName * 文件名 * @param chilPath * 子文件夹路径 * @return */ public static byte[] downFile(String fileName, String chilPath) { FTPClient connect = getConnect(chilPath); return downFile(fileName, connect); }
3.调用连接,下载文件(如果没有父级结构)
/** * 下载文件 无子文件夹 * * @param fileName * 文件名 * @return */ public static byte[] downFile(String fileName) { FTPClient connect = getConnect(null); return downFile(fileName, connect); }
4.真正的调用连接,获取文件在这里,以上两个方法都调用这个方法。
public static byte[] downFile(String fileName, FTPClient connect) { InputStream in = null; try { FTPFile[] fs = connect.listFiles(fileName); // 遍历所有文件,找到指定的文件 for (FTPFile file : fs) { if (file.getName().equals(fileName)) { connect.setBufferSize(1024); connect.setControlEncoding("UTF-8"); in = connect.retrieveFileStream(fileName); byte[] b = input2byte(in); return b; } } } catch (Exception e) { } finally { try { if (in != null) { in.close(); } connect.logout(); } catch (IOException e) { } } return null; }
5.上边那个方法需要流转byte[ ],所以写了一个input2byte
public static final byte[] input2byte(InputStream inStream) throws IOException { ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); byte[] buff = new byte[100]; int rc = 0; while ((rc = inStream.read(buff, 0, 100)) > 0) { swapStream.write(buff, 0, rc); } byte[] in2b = swapStream.toByteArray(); return in2b; }
6.自动识别是否含有父级文件夹,以区别调用2还是3方法
/** * 获取指定目录文件名 * * @param path * @return */ public static String getFileNameByPath(String path) { // 先将\\替换成/ String tempPath = path.replace("\\", "/"); return path.substring(tempPath.lastIndexOf("/") + 1); }
7.调用浏览器,下载
public Object downloadFile(String filePath, HttpServletResponse response ) { // 子目录地址 String childPath = getParentPath(filePath, 1); // 文件名 String fileName = getFileNameByPath(filePath); // 文件后缀名 String fileSuffixName = fileName.substring(fileName.lastIndexOf(".") + 1); try { byte[] outPutStream = null; if(childPath == null) { // 子目录不存在 outPutStream = downFile(fileName); }else { outPutStream = downFile(fileName, childPath); } if(outPutStream != null) { response.reset(); response.setContentType("application/" + fileSuffixName + ";" + "charset = UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=" + fileName); response.getOutputStream().write(outPutStream); // 以上为一种 // response.reset(); // response.setContentType("text/html; charset=utf-8"); // response.setHeader("Content-Disposition","attachment; filename=" + URLEncoder.encode(完整的文件名+后缀名),"utf-8"); // response.getOutputStream().write(outPutStream); return 200; } else { response.getWriter().write("未找到发票文件,或发票还未开出"); //return 500; } } catch (Exception e) { e.printStackTrace(); } return 200; }
调用实例
1.我写了一个DownloadServlet,在doGet方法中加入以下,就可调用下载文件了。
String fp=request.getParameter("fp"); if(StringUtils.isNotEmpty(fp)) { downloadFile(fp, response); }
原文:https://www.cnblogs.com/zhanglixuan/p/10895735.html