从ftp获取文件并生成压缩包
生活随笔
收集整理的這篇文章主要介紹了
从ftp获取文件并生成压缩包
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
之前寫的有bug啊 每人說..
依賴
<dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><version>3.4</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.3.2</version></dependency><dependency><groupId>org.apache.ant</groupId><artifactId>ant</artifactId><version>1.10.5</version></dependency>可選擇多個路徑進行壓縮
依賴
<dependency><groupId>org.apache.ant</groupId><artifactId>ant</artifactId><version>1.10.5</version> </dependency>可選擇多個路徑進行壓縮
依賴
<dependency><groupId>org.apache.ant</groupId><artifactId>ant</artifactId><version>1.10.5</version> </dependency>可選擇多個路徑進行壓縮
package per.qiao.utils.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 org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory;import java.io.File; import java.io.IOException; import java.io.InputStream;/*** Create by IntelliJ Idea 2018.2** @author: qyp* Date: 2019-07-19 17:10*/ public class FtpFileZipUtls {private final static Logger logger = LoggerFactory.getLogger(FtpFileZipUtls.class);/*** 加載一個非空文件夾*/private static void loadFile(FTPClient ftp, String dirPath, ZipOutputStream zos) throws IOException {FTPFile[] ftpFiles = ftp.listFiles();System.out.println(ftp.printWorkingDirectory());// 該if判斷是否是一個文件 如果是一個空文件 直接添加到壓縮包if (ftp.changeToParentDirectory()) {logger.info("退回到: " + ftp.printWorkingDirectory());boolean b = ftp.changeWorkingDirectory(getFileName(dirPath.substring(dirPath.lastIndexOf(File.separator) + 1)));logger.info("進入: " + ftp.printWorkingDirectory());// 是一個空文件夾if (b && (ftpFiles == null || ftpFiles.length <= 0)) {zos.putNextEntry(new ZipEntry(getFileName(dirPath) + File.separator));return;}}for (FTPFile f : ftpFiles) {if (f.isFile()) {InputStream in = ftp.retrieveFileStream(f.getName());zos.putNextEntry(new ZipEntry(getFileName(dirPath) + File.separator + f.getName()));addToZOS(in, zos);ftp.completePendingCommand();} else {if (ftp.changeWorkingDirectory(f.getName())) {loadFile(ftp, dirPath + File.separator + f.getName(), zos);// ftp指針移動到上一層ftp.changeToParentDirectory();}}}}/*** 將文件夾中的.替換為^^* @param sb* @return*/private static void replaceFileName(StringBuilder sb, String onepath) {sb.replace(sb.indexOf(onepath), sb.indexOf(onepath) + onepath.length(), onepath.replaceAll("\\.", "^^"));}/*** 將文件夾路徑中的 ^^ 替換成.* @param sb* @return*/private static String getFileName(String sb) {StringBuilder result = new StringBuilder(sb);do {if (result.indexOf("^^") > -1) {result.replace(result.indexOf("^^"), result.indexOf("^^") + 2, ".");}} while (result.indexOf("^^") >= 0);return result.toString();}/*** 切換目錄 返回切換的層級數* @param sb* @param ftp* @return 切換的層級數* @throws IOException*/private static int exchageDir(StringBuilder sb, FTPClient ftp) throws IOException {// 計入進入的文件夾的次數,方便回退int level = 0;String[] pathes = sb.toString().split("/");for (int i = 0, len = pathes.length; i < len; i++) {String onepath = pathes[i];if (onepath == null || "".equals(onepath.trim())) {continue;}//文件排除boolean flagDir = ftp.changeWorkingDirectory(onepath);if (flagDir) {level++;if (onepath.contains(".")) {//把文件夾中的.用^^代替replaceFileName(sb, onepath);}logger.info("成功連接ftp目錄:" + ftp.printWorkingDirectory());} else {logger.warn("連接ftp目錄失敗:" + ftp.printWorkingDirectory());}}return level;}/*** 處理單個文件和空文件夾的情況 處理了返回true 未處理返回false* 注意:這里是指數組中給的路徑直接是文件或者空文件夾的情況* @param ftp* @param path 需要壓縮的文件(文件夾)路徑(相對根)* @param zos* @return* @throws IOException*/public static boolean delFile(FTPClient ftp, StringBuilder path, ZipOutputStream zos) throws IOException {int times = exchageDir(path, ftp);String fileRelativePaht = path.toString();String[] split = fileRelativePaht.split("/");// 是否處理過boolean isDel = false;//有父級目錄if (split != null && split.length > 0) {String lastSegmeng = split[split.length - 1];//path直接是文件if (split[split.length - 1].contains(".")) {zos.putNextEntry(new ZipEntry(fileRelativePaht));addToZOS(ftp.retrieveFileStream(lastSegmeng), zos);ftp.completePendingCommand();isDel = true;} else if (ftp.listFiles().length <= 0) {// 空文件夾zos.putNextEntry(new ZipEntry(fileRelativePaht + File.separator));isDel = true;}// 如果被處理過(空文件夾或者直接給的文件的路徑),退回到根路徑(以免污染下次循環的ftp指針)if (isDel) {for (int i = 0; i < times; i++) {ftp.changeToParentDirectory();}}}return isDel;}/*** 添加文件到壓縮流* @param in 輸入流(一般就直接是從FTP中獲取的)* @param zos 壓縮輸出流* @throws IOException*/public static void addToZOS(InputStream in, ZipOutputStream zos) throws IOException {byte[] buf = new byte[1024];//BufferedOutputStream bzos = new BufferedOutputStream(zos);try {for (int len; (len = (in.read(buf))) != -1; ) {zos.write(buf, 0 , len);}} catch (IOException e) {System.out.println("流轉換異常");throw e;} finally {if (in != null) {try {in.close();} catch (IOException e) {System.out.println("關流異常");e.printStackTrace();}}}}public static FTPClient getFtpClient(String path) throws Exception {String server = "127.0.0.1";int port = 21;String username = "test";String password = "test"; // path = "/FTPStation/";FTPClient ftpClient = connectServer(server, port, username, password, path);return ftpClient;}/**** @param server* @param port* @param username* @param password* @param path 連接的節點(相對根路徑的文件夾)* @return*/public static FTPClient connectServer(String server, int port, String username, String password, String path) throws IOException {path = path == null ? "" : path;FTPClient ftp = new FTPClient();//下面四行代碼必須要,而且不能改變編碼格式,否則不能正確下載中文文件// 如果使用serv-u發布ftp站點,則需要勾掉“高級選項”中的“對所有已收發的路徑和文件名使用UTF-8編碼”ftp.setControlEncoding("GBK");FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);conf.setServerLanguageCode("zh");ftp.configure(conf);// 判斷ftp是否存在ftp.connect(server, port);ftp.setDataTimeout(2 * 60 * 1000);if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {ftp.disconnect();System.out.println(server + "拒絕連接");}//登陸ftpboolean login = ftp.login(username, password);if (logger.isDebugEnabled()) {if (login) {logger.debug("登陸FTP成功! ip: " + server);} else {logger.debug("登陸FTP失敗! ip: " + server);}}//根據輸入的路徑,切換工作目錄。這樣ftp端的路徑就可以使用相對路徑了exchageDir(new StringBuilder(path), ftp);return ftp;}/*** 多FTP路徑壓縮* @param ftp* @param savePath* @param filePaths* @throws Exception*/public static void zipFileByPaths(FTPClient ftp, String savePath, String[] filePaths) throws Exception {try (ZipOutputStream zos = getOutPutStream(savePath)) {for (String path : filePaths) {StringBuilder sb = new StringBuilder(path);//delFile時進入的文件夾的路徑(當前需要遍歷的文件的路徑)String before = ftp.printWorkingDirectory();if (delFile(ftp, sb, zos)) {continue;}loadFile(ftp, sb.toString(), zos);// 文件加載完畢后,需要將ftp的指針退到開始狀態String after = ftp.printWorkingDirectory();backPath(before, after, ftp);}zos.flush();} catch (Exception e) {logger.error("多路徑文件壓縮失敗");e.printStackTrace();throw e;}}/*** ftp 指針回退* @param end* @param start* @param ftp* @throws IOException*/private static void backPath(String end, String start, FTPClient ftp) throws IOException {for (; !end.equals(start);) {if (ftp.changeToParentDirectory()) {start = ftp.printWorkingDirectory();}}}/*** 獲取apache的ZipOutputStream流* @param savePath 保存壓縮文件的路徑* @return* @throws FileNotFoundException 如果保存路徑不存在,那么將會拋異常*/public static ZipOutputStream getOutPutStream(String savePath) throws FileNotFoundException {//輸出的壓縮原始文件流fileDir + "\\" + "詳情.zip"FileOutputStream f = new FileOutputStream(new File(savePath));// 計算和校驗文件CheckedOutputStream csum = new CheckedOutputStream(f, new CRC32());// 輸出的壓縮文件流ZipOutputStream zos = new ZipOutputStream(csum);zos.setComment("dist文件壓縮流");//設置壓縮工具右邊的文字編碼 防止右邊的說明文字亂碼zos.setEncoding(System.getProperty("sun.jnu.encoding"));return zos;}public static void main(String[] args) throws Exception {String[] paths = {"/CAD/你好.txt", "/CAD/1.第一層"};String savePath = "e:/temp/zz.zip";//連接到的節點String rootDir = "/CAD";FTPClient ftp = getFtpClient(rootDir);zipFileByPaths(ftp, savePath, paths);}}轉載于:https://www.cnblogs.com/qiaozhuangshi/p/11216454.html
總結
以上是生活随笔為你收集整理的从ftp获取文件并生成压缩包的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: @EnableGlobalMethodS
- 下一篇: 生成ftp文件的目录树