import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
import java.util.ArrayList
import java.util.Iterator
import java.util.List
import java.util.Properties
import java.util.Vector
import org.apache.commons.lang.ArrayUtils
import com.huawei.bme.commons.om.log.DebugLog
import com.huawei.bme.commons.om.log.LogFactory
import com.huawei.icity.commons.constants.KeyConstant
import com.huawei.icity.commons.constants.NumberConstant
import com.huawei.icity.commons.exception.SPMException
import com.huawei.icity.commons.log.IcityLogFactory
import com.huawei.icity.commons.log.IcityRuntimeLog
import com.huawei.icity.commons.sysconfig.StaticInitData
import com.huawei.icity.commons.utils.StringTools
import com.huawei.icity.omp.common.util.CommonTools
import com.huawei.icity.omp.interfaces.hint.constant.TimetaskConstants
import com.huawei.mdmc.bfm.cms.assist.common.domain.SingleTableModel
import com.jcraft.jsch.Channel
import com.jcraft.jsch.ChannelSftp
import com.jcraft.jsch.ChannelSftp.LsEntry
import com.jcraft.jsch.JSch
import com.jcraft.jsch.JSchException
import com.jcraft.jsch.Session
import com.jcraft.jsch.SftpException
/**
* SFTP公共处简胡理类 〈渗烂提供SFTP文件上传,下载,获取指定目录 下文件名集合, 获取指定目录 下文件集合等方法>
*
* @author mKF75022
* @version iCity Manager V100R002 2012-7-3
* @since iCity Manager V100R002C01
*/
public class SFTPTool
{
/**
* 调测日志记录器。
*/
private static final DebugLog DEBUGGER = LogFactory.getDebugLog(SFTPTool.class)
/**
* 运行日志记录器。
*/
private static final IcityRuntimeLog RUNTIMELOGGER = IcityLogFactory
.getRuntimeLog(SFTPTool.class)
/**
* Sftp客户端对拦喊拦象
*/
private ChannelSftp sftp = null
/**
* SFTP IP地址
*/
private String ip
/**
* SFTP 端口
*/
private String port
/**
* SFTP 用户名
*/
private String userName
/**
* SFTP 密码
*/
private String password
/**
* SFTP上传模式:BINARY
*/
// private static final int BINARY_FILE_TYPE = 2
/**
*
* 获取实例
*
* @return SFTPTool newinstance实例
*
*/
public static SFTPTool getNewInstance()
{
return new SFTPTool()
}
/**
* 初始化连接参数
*
* @param sftpIP
*IP
* @param sftpPort
*端口
* @param sftpUsername
*用户名
* @param sftpPassword
*密码
*/
public void init(String sftpIP, String sftpPort, String sftpUsername, String sftpPassword)
{
// 获取SFTP连接信息
this.ip = sftpIP
this.port = sftpPort
this.userName = sftpUsername
this.password = sftpPassword
}
/**
* 从SFTP将符合约定命名的文件都下载到本地 .
*
* @param sftpDir
*SFTP服务器文件存放路径
* @param locDir
*本地文件存放路径
* @param regex
*指定文件名的格式
* @param needBackup
*是否需要文件备份(true:是false:否)
* @param needFullMatch
*是否要求全局匹配(true:是false:否)
* @param deleteFtpFile
*the delete ftp file
* @return 下载到本地的文件列表
*/
public List<File>synSFTPFileToLocal(String sftpDir, String locDir, String regex,
boolean needBackup, boolean needFullMatch, boolean deleteFtpFile)
{
List<File>files = new ArrayList<File>(KeyConstant.INITIAL_NUMBER)
try
{
this.connect(ip, Integer.parseInt(this.port), userName, password)
// 获得FTP上文件名称列表
List<String>ftpFileNameList = this.listFiles(sftpDir, regex, needFullMatch)
File localFile = null
int size = ftpFileNameList.size()
// 根据每个FTP文件名称创建本地文件。
for (int i = 0i <sizei++)
{
// 下载源文件
localFile = this.download(sftpDir, locDir, ftpFileNameList.get(i), deleteFtpFile)
if (localFile.exists())
{
files.add(localFile)
}
if (needBackup)
{
// 备份源文件生成默认备份文件路径(据请求文件路径,生成同级目录的备份文件夹绝对路径)
String parentDir = sftpDir.substring(NumberConstant.INT_0,
sftpDir.lastIndexOf("/") + 1)
String backupDir = parentDir + TimetaskConstants.DEFAULT_BACKUP_DIRNAME
boolean bakExists = openDir(backupDir)
if (bakExists)
{
this.uploadFile(backupDir, localFile)
}
else
{
boolean parentExists = openDir(parentDir)
if (parentExists)
{
sftp.mkdir(TimetaskConstants.DEFAULT_BACKUP_DIRNAME)
this.uploadFile(backupDir, localFile)
}
else
{
DEBUGGER.error("sftp parentDir no exisits ")
}
}
}
}
}
catch (Exception e)
{
DEBUGGER.error("synSFTPFileToLocal Exception", e)
}
finally
{
this.disconnect()
}
return files
}
/**
* 连接sftp服务器
*
* @param sftpip
*ip地址
* @param sftpport
*端口
* @param sftpusername
*用户名
* @param sftppassword
*密码
* @return channelSftp
* @throws SPMException
*/
public ChannelSftp connect(String sftpip, int sftpport, String sftpusername, String sftppassword)
{
sftp = new ChannelSftp()
try
{
JSch jsch = new JSch()
jsch.getSession(sftpusername, sftpip, sftpport)
Session sshSession = jsch.getSession(sftpusername, sftpip, sftpport)
RUNTIMELOGGER.info("Session created")
sshSession.setPassword(sftppassword)
Properties sshConfig = new Properties()
sshConfig.put("StrictHostKeyChecking", "no")
sshSession.setConfig(sshConfig)
// 设置超时时间为
sshSession.setTimeout(Integer.parseInt(StaticInitData.getFtpConnectTimeOut())
* NumberConstant.INT_1000)
sshSession.connect()
Channel channel = sshSession.openChannel("sftp")
channel.connect()
sftp = (ChannelSftp) channel
// 设置文件类型
// ftpClient.setFileType(BINARY_FILE_TYPE)
// 与防火墙相关
// ftpClient.enterLocalPassiveMode()
}
catch (JSchException e)
{
DEBUGGER.error("JSchException : {}", e)
}
return sftp
}
// /**
// * 创建指定文件夹
// *
// * @param dirName
// * dirName
// */
// public void mkDir(String dirName)
// {
// try
// {
// sftp.mkdir(dirName)
// }
// catch (SftpException e)
// {
// DEBUGGER.error("mkDir Exception : " + e)
// }
// }
/**
* 创建指定文件夹
*
* @param dirName
*dirName
*/
public void mkDir(String dirName)
{
String[] dirs = dirName.split("/")
try
{
String now = sftp.pwd()
for (int i = 0i <dirs.lengthi++)
{
boolean dirExists = openDir(dirs[i])
if (!dirExists)
{
sftp.mkdir(dirs[i])
sftp.cd(dirs[i])
}
}
sftp.cd(now)
}
catch (SftpException e)
{
DEBUGGER.error("mkDir Exception : " + e)
}
}
/**
* 打开指定目录
*
* @param directory
*directory
* @return 是否打开目录
*/
public boolean openDir(String directory)
{
try
{
sftp.cd(directory)
return true
}
catch (SftpException e)
{
DEBUGGER.error("openDir Exception : " + e)
return false
}
}
最近接到一个产品需求是给指定的 sftp 服务谨友器的指定目录定时推送文件数据。
因为项目组已有现成的组件可以轻松实现 sftp 服务器文件的快速上传,本来是一件很容易的事情,但是问题出现在这个指定的 sftp 服务器所指定的密码带有系统关键字和一些特殊字符,导致现在的组件在解析过程中会失败。
因此重新开发了下面的这套脚本来满足这个特殊的需求。
Python代码
sftp配置文件代码
(1). yaml 模块
导入 yaml 模块前可以使用以下命令进行模块的安装
yaml 模块在这里的作用是读取 sftp 配置文件代码,将指定key: test_file_upload 下的 key:value 的值转换为字典。
例如:load_config_from_param_conf 函数中的返回值就是使用 yaml 读取正晌猜到 sftp 配置文件代码后,返回 key: test_file_upload 下配置选项值。
格式如下:
最后将返回值传给 upload 函数作为参数。
(2). OptionParser 模块
按照 yaml 模块的安装方法,先安装 optparse 模块后,然后在文件中从optparse 中导入 OptionParser 模块
在这里我使用了 OptionParser 这个类实例化了一个对象:opt_parser,通过对象来调用 add_option 方法添加了2个参数,分别是:node, local_file
1). 形参:--node,实参:node
所代表的业务含义是:指定要上传的 sftp 的节点,具体参数值对应 sftp配置文件代码中的举型 test_file_upload
2). 形参:--local_file,实参:local_file
所代表的业务含义是:指定本地需要被上传到 sftp 服务器的具体文件路径
3). 调用命令
4). add_option()方法
参数:action的枚举
store: 参数列表中带有--node, 那么就会将下一个元素即:test_file_upload 作为其 dest 实参 node 的值如果没有--node,那么对应的node的值就为 None
store_true: 参数列表中有--local_file, 那么其 dest 实参 local_file 的值就为 True否者就为 default 定义的默认值,这里没有给定 default 的默认值
store_false: 参数列表中有--local_file, 那么其 dest 实参 local_file 的值就为 False否者就为 default 定义的默认值,这里没有给定 default 的默认值
参数:type
type是指定传入参数的类型,这里的参数类型为 string 类型。
参数:dest
dest是参数传入后由哪个变量来存储的,后面代码对该参数的引用也是使用这里定义的变量名来引用的。
参数:default
default 是与 action 的值结合使用的。
参数:help
help相当于帮助说明文档,用于描述这个参数的含义。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)