All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dromara.hutool.extra.ftp.AbstractFtp Maven / Gradle / Ivy

There is a newer version: 6.0.0.M3
Show newest version
/*
 * Copyright (c) 2013-2024 Hutool Team and hutool.cn
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.dromara.hutool.extra.ftp;

import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.io.file.FileNameUtil;
import org.dromara.hutool.core.io.file.FileUtil;
import org.dromara.hutool.core.text.CharUtil;
import org.dromara.hutool.core.text.StrUtil;

import java.io.File;
import java.util.List;

/**
 * 抽象FTP类,用于定义通用的FTP方法
 *
 * @author looly
 * @since 4.1.14
 */
public abstract class AbstractFtp implements Ftp {

	protected FtpConfig ftpConfig;

	@Override
	public FtpConfig getConfig() {
		return this.ftpConfig;
	}

	/**
	 * 构造
	 *
	 * @param config FTP配置
	 * @since 5.3.3
	 */
	protected AbstractFtp(final FtpConfig config) {
		this.ftpConfig = config;
	}

	@Override
	public boolean exist(final String path) {
		if (StrUtil.isBlank(path)) {
			return false;
		}
		// 目录验证
		if (isDir(path)) {
			return true;
		}
		if (CharUtil.isFileSeparator(path.charAt(path.length() - 1))) {
			return false;
		}

		final String fileName = FileNameUtil.getName(path);
		if (StrUtil.DOT.equals(fileName) || StrUtil.DOUBLE_DOT.equals(fileName)) {
			return false;
		}

		// 文件验证
		final String dir = StrUtil.defaultIfEmpty(StrUtil.removeSuffix(path, fileName), StrUtil.DOT);
		// issue#I7CSQ9 检查父目录为目录且是否存在
		if (!isDir(dir)) {
			return false;
		}
		final List names;
		try {
			names = ls(dir);
		} catch (final FtpException ignore) {
			return false;
		}
		return containsIgnoreCase(names, fileName);
	}

	@Override
	public void mkDirs(final String dir) {
		final String[] dirs = StrUtil.trim(dir).split("[\\\\/]+");

		final String now = pwd();
		if (dirs.length > 0 && StrUtil.isEmpty(dirs[0])) {
			//首位为空,表示以/开头
			this.cd(StrUtil.SLASH);
		}
		for (final String s : dirs) {
			if (StrUtil.isNotEmpty(s)) {
				boolean exist = true;
				try {
					if (!cd(s)) {
						exist = false;
					}
				} catch (final FtpException e) {
					exist = false;
				}
				if (!exist) {
					//目录不存在时创建
					mkdir(s);
					cd(s);
				}
			}
		}
		// 切换回工作目录
		cd(now);
	}

	/**
	 * 下载文件-避免未完成的文件
* 来自:https://gitee.com/dromara/hutool/pulls/407
* 此方法原理是先在目标文件同级目录下创建临时文件,下载之,等下载完毕后重命名,避免因下载错误导致的文件不完整。 * * @param path 文件路径 * @param outFile 输出文件或目录 * @param tempFileSuffix 临时文件后缀,默认".temp" * @since 5.7.12 */ public void download(final String path, File outFile, String tempFileSuffix) { if (StrUtil.isBlank(tempFileSuffix)) { tempFileSuffix = ".temp"; } else { tempFileSuffix = StrUtil.addPrefixIfNot(tempFileSuffix, StrUtil.DOT); } // 目标文件真实名称 final String fileName = outFile.isDirectory() ? FileNameUtil.getName(path) : outFile.getName(); // 临时文件名称 final String tempFileName = fileName + tempFileSuffix; // 临时文件 outFile = new File(outFile.isDirectory() ? outFile : outFile.getParentFile(), tempFileName); try { download(path, outFile); // 重命名下载好的临时文件 FileUtil.rename(outFile, fileName, true); } catch (final Throwable e) { // 异常则删除临时文件 FileUtil.del(outFile); throw new FtpException(e); } } // ---------------------------------------------------------------------------------------------------------------------------------------- Private method start /** * 是否包含指定字符串,忽略大小写 * * @param names 文件或目录名列表 * @param nameToFind 要查找的文件或目录名 * @return 是否包含 */ private static boolean containsIgnoreCase(final List names, final String nameToFind) { if (StrUtil.isEmpty(nameToFind)) { return false; } return CollUtil.contains(names, nameToFind::equalsIgnoreCase); } // ---------------------------------------------------------------------------------------------------------------------------------------- Private method end }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy