我正在尝试在SSIS中实现解决方案,其中我们必须使用Winzip从SFTP下载文件。 SFTP中的文件名类似于ABC_CNT_03_06_2019_02-05_AM.csv
。要求是下载当前日期文件。在这种情况下,我们必须忽略文件名中的时间部分。
当前,我正在尝试实施以下解决方案:
ABC_CNT_03_06_2018*.csv
C:\Program Files (x86)\WinSCP\WinSCP.com
/script="F:\Upload.txt /parameter " + User::Filename
option batch on
option confirm off
open username: password@sftp2.ftpname.com
get /%1% F:\downloadfolder
close exit
试图运行该程序包,但是它不起作用。 您能再提出建议吗?
答案 0 :(得分:1)
对于这种情况,我建议将脚本任务与WinSCP .NET程序集一起使用,这将允许您使用C#功能在传输之前验证文件上的日期。下面是此过程的一个示例。由于您将文件名(包括日期)的开头存储在变量中,因此String.StartsWith
属性使用Name
方法,因为该方法仅返回文件名,而不包含文件夹路径。 String.EndsWith
方法还用于仅匹配您帖子中提到的CSV文件。保存文件名的SSIS变量需要添加到“脚本任务”的ReadOnlyVariables
字段中,如果要保存它们,则需要添加保存文件夹路径的变量。如果遇到与加载WinSCP程序集有关的错误,则可以使用ResolveEventHandler
委托来解决此问题,如下所示。 WinSCP dll的下载位置将是发送到LoadFile
方法的路径。看起来您每天只需要一个文件,但是如果一天中会有多个文件,则会使用一个列表。
using System.Linq;
using WinSCP;
using System.Collections.Generic;
//load WinSCPnet.dll
static ScriptMain()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
if (args.Name.ToUpper().Contains("WINSCPNET"))
{
string path = @"C:\WinSCP Download Path\";
return System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(path, "WinSCPnet.dll"));
}
return null;
}
public void Main()
{
//get file name and local/remote paths from SSIS variables.
string fileDateName = Dts.Variables[“User::FileDateName”].Value.ToString();
string remotePath = Dts.Variables[“User::RemoteFilePath”].Value.ToString();
string localPath = Dts.Variables[“User::LocalFilePath”].Value.ToString();
SessionOptions sessOpt = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = "SFTPsite.com",
UserName = "user",
Password = "password",
SshHostKeyFingerprint = "Your SshHostKeyFingerprint"
};
using (Session session = new Session())
{
session.Open(sessOpt);
TransferOptions transferOptions = new TransferOptions();
transferOptions.TransferMode = TransferMode.Binary;
RemoteDirectoryInfo rdi = session.ListDirectory(remotePath);
//confirm beginning of file name and extension
List<string> fileList = rdi.Files.Where(file => (file.Name.StartsWith(fileDateName))
&& (file.FullName.EndsWith(".csv"))).Select(file => file.FullName).ToList();
foreach (string s in fileList)
{
//transfer files
session.GetFiles(s, localPath, false, transferOptions);
}
}
}