WinSCP.Net,文件夹未从远程复制到本地
WinSCP.Net, folder is not copied from remote to local
我一直在使用 WinSCP 定期从 Unix 服务器下载文件到 Windows 服务器,并且一直没有问题。我还检查远程文件是否较旧或已经存在(不要复制)。
现在,我必须做同样的事情,但这次我必须下载文件和文件夹。文件复制得很好,但文件夹不是。在玩设置时,我得到它来复制文件夹的内容,但它们被复制到我的本地根文件夹;我以为 WinSCP 会复制所有内容。
在下面的代码中,LocalFolder 是 Z:\My_Data,LogRootFolder 是 /xyz/gtc/a00/
遥控器上的文件夹结构是 /xyz/gtc/a00/ABCD/outcomes/ 子文件夹“备份”,其中有许多子文件夹命名为日期(例如 /xyz/gtc/a00/ABCD/outcomes/backup/2021-06- 23/)
复制“backup/2021-xx-xx/”个文件和文件夹中的none个,或者全部复制到Z:\My_Data\ABCD
设置会话后,调用SFTP_Session:
string sRemotePath = LogRootFolder + "ABCD/outcomes/";
string sLocalFolder = Path.Combine(LocalFolder, @"ABCD\");
if (SFTP_Session.Opened)
{
using (SFTP_Session)
{
SFTP_Session.QueryReceived += (sender, e) =>
{
...
e.Continue();
};
//var opts = EnumerationOptions.EnumerateDirectories | EnumerationOptions.AllDirectories;
//IEnumerable<RemoteFileInfo> fileInfos = SFTP_Session.EnumerateRemoteFiles(sRemotePath, "*.dat", opts); <-- This copies files in folder(s) to m local root folder
Regex mask = new Regex(@"\.(dat|err)$", RegexOptions.IgnoreCase);
IEnumerable<RemoteFileInfo> fileInfos =
SFTP_Session.EnumerateRemoteFiles(sRemotePath, null, EnumerationOptions.AllDirectories)
.Where(fileInfo => mask.Match(fileInfo.Name).Success)
.ToList();
foreach (RemoteFileInfo fileInfo in fileInfos)
{
string localFilePath = Path.Combine(sLocalFolder, fileInfo.Name);
if (fileInfo.IsDirectory)
{
// Create local subdirectory, if it does not exist yet
if (!Directory.Exists(localFilePath))
{
Directory.CreateDirectory(localFilePath);
}
}
else
{
string remoteFilePath = RemotePath.EscapeFileMask(fileInfo.FullName);
// If file does not exist in local folder, download
if (!File.Exists(localFilePath))
{
bDownload = true;
}
else // If file exists in local folder but is older, download; else skip
{
DateTime remoteWriteTime = SFTP_Session.GetFileInfo(remoteFilePath).LastWriteTime;
DateTime localWriteTime = File.GetLastWriteTime(localFilePath);
if (remoteWriteTime > localWriteTime)
{
bDownload = true;
}
else
{
bDownload = false;
}
}
if (bDownload)
{
// Download file
TransferOptions oTrRes = new TransferOptions();
oTrRes.TransferMode = TransferMode.Automatic; //The Transfer Mode - Automatic, Binary, or Ascii
oTrRes.FilePermissions = null; //Permissions applied to remote files; null for default permissions. Can set user, Group, or other Read/Write/Execute permissions.
oTrRes.PreserveTimestamp = false; //Set last write time of destination file to that of source file - basically change the timestamp to match destination and source files.
oTrRes.ResumeSupport.State = TransferResumeSupportState.Off;
TransferOperationResult transferResult = SFTP_Session.GetFiles(remoteFilePath, localFilePath, false, oTrRes);//.Replace("\","")); // I thought this would get files AND folders
// Throw on any error
transferResult.Check();
foreach (TransferEventArgs transfer in transferResult.Transfers)
{
// Store local file info in a data table for processing later
...
}
SessionRemoteExceptionCollection srec = transferResult.Failures;
foreach (SessionRemoteException sre in srec)
{
// Log errors
}
// Did the download succeeded?
if (!transferResult.IsSuccess)
{
// Log error (but continue with other files)
}
}
}
}
最后,在本地文件夹中,我看到下载和复制的文件以及我创建的子文件夹(使用上面的代码),但这些文件夹中没有文件。看不到我在这里遗漏了什么。
您的代码基本上是将远程目录同步到本地目录。
无需修复您的代码,您只需调用 Session.SynchronizeDirectories
即可替换大部分代码:
https://winscp.net/eng/docs/library_session_synchronizedirectories
首先在 WinSCP GUI 中尝试同步,看看它是否满足您的需要。
- 如果需要对同步文件做一些处理,使用
Session.SynchronizeDirectories
返回的SynchronizationResult
。它包含所有同步文件的列表。
- 如果您需要从同步中排除某些文件,请使用
TransferOptions.FileMask
。
我一直在使用 WinSCP 定期从 Unix 服务器下载文件到 Windows 服务器,并且一直没有问题。我还检查远程文件是否较旧或已经存在(不要复制)。
现在,我必须做同样的事情,但这次我必须下载文件和文件夹。文件复制得很好,但文件夹不是。在玩设置时,我得到它来复制文件夹的内容,但它们被复制到我的本地根文件夹;我以为 WinSCP 会复制所有内容。
在下面的代码中,LocalFolder 是 Z:\My_Data,LogRootFolder 是 /xyz/gtc/a00/
遥控器上的文件夹结构是 /xyz/gtc/a00/ABCD/outcomes/ 子文件夹“备份”,其中有许多子文件夹命名为日期(例如 /xyz/gtc/a00/ABCD/outcomes/backup/2021-06- 23/)
复制“backup/2021-xx-xx/”个文件和文件夹中的none个,或者全部复制到Z:\My_Data\ABCD
设置会话后,调用SFTP_Session:
string sRemotePath = LogRootFolder + "ABCD/outcomes/";
string sLocalFolder = Path.Combine(LocalFolder, @"ABCD\");
if (SFTP_Session.Opened)
{
using (SFTP_Session)
{
SFTP_Session.QueryReceived += (sender, e) =>
{
...
e.Continue();
};
//var opts = EnumerationOptions.EnumerateDirectories | EnumerationOptions.AllDirectories;
//IEnumerable<RemoteFileInfo> fileInfos = SFTP_Session.EnumerateRemoteFiles(sRemotePath, "*.dat", opts); <-- This copies files in folder(s) to m local root folder
Regex mask = new Regex(@"\.(dat|err)$", RegexOptions.IgnoreCase);
IEnumerable<RemoteFileInfo> fileInfos =
SFTP_Session.EnumerateRemoteFiles(sRemotePath, null, EnumerationOptions.AllDirectories)
.Where(fileInfo => mask.Match(fileInfo.Name).Success)
.ToList();
foreach (RemoteFileInfo fileInfo in fileInfos)
{
string localFilePath = Path.Combine(sLocalFolder, fileInfo.Name);
if (fileInfo.IsDirectory)
{
// Create local subdirectory, if it does not exist yet
if (!Directory.Exists(localFilePath))
{
Directory.CreateDirectory(localFilePath);
}
}
else
{
string remoteFilePath = RemotePath.EscapeFileMask(fileInfo.FullName);
// If file does not exist in local folder, download
if (!File.Exists(localFilePath))
{
bDownload = true;
}
else // If file exists in local folder but is older, download; else skip
{
DateTime remoteWriteTime = SFTP_Session.GetFileInfo(remoteFilePath).LastWriteTime;
DateTime localWriteTime = File.GetLastWriteTime(localFilePath);
if (remoteWriteTime > localWriteTime)
{
bDownload = true;
}
else
{
bDownload = false;
}
}
if (bDownload)
{
// Download file
TransferOptions oTrRes = new TransferOptions();
oTrRes.TransferMode = TransferMode.Automatic; //The Transfer Mode - Automatic, Binary, or Ascii
oTrRes.FilePermissions = null; //Permissions applied to remote files; null for default permissions. Can set user, Group, or other Read/Write/Execute permissions.
oTrRes.PreserveTimestamp = false; //Set last write time of destination file to that of source file - basically change the timestamp to match destination and source files.
oTrRes.ResumeSupport.State = TransferResumeSupportState.Off;
TransferOperationResult transferResult = SFTP_Session.GetFiles(remoteFilePath, localFilePath, false, oTrRes);//.Replace("\","")); // I thought this would get files AND folders
// Throw on any error
transferResult.Check();
foreach (TransferEventArgs transfer in transferResult.Transfers)
{
// Store local file info in a data table for processing later
...
}
SessionRemoteExceptionCollection srec = transferResult.Failures;
foreach (SessionRemoteException sre in srec)
{
// Log errors
}
// Did the download succeeded?
if (!transferResult.IsSuccess)
{
// Log error (but continue with other files)
}
}
}
}
最后,在本地文件夹中,我看到下载和复制的文件以及我创建的子文件夹(使用上面的代码),但这些文件夹中没有文件。看不到我在这里遗漏了什么。
您的代码基本上是将远程目录同步到本地目录。
无需修复您的代码,您只需调用 Session.SynchronizeDirectories
即可替换大部分代码:
https://winscp.net/eng/docs/library_session_synchronizedirectories
首先在 WinSCP GUI 中尝试同步,看看它是否满足您的需要。
- 如果需要对同步文件做一些处理,使用
Session.SynchronizeDirectories
返回的SynchronizationResult
。它包含所有同步文件的列表。 - 如果您需要从同步中排除某些文件,请使用
TransferOptions.FileMask
。