SFTP GetFiles throws Index out of the bounds Exception

0 votes
asked May 2, 2012 by Mali (320 points)
edited Jul 12, 2012

Hi,

I am trying to use the GetFiles Method on an SFTP connection to our servers. It throws an Index is out of the bounds of an array Exception. Any thoughts on how to resolve this will be appreciated.

The directory structure in the Server is as follows

/Inbox
   /Test1.txt
   /Test2.txt
/Data

And the program code line is:

client.GetFiles(@"/Inbox", @"C:\DataCollection\TestFiles\Download\GrpDownload", SftpBatchTransferOptions.XCopy, SftpActionOnExistingFiles.OverwriteAll);

I find that C# program throws the Exception as follows:

Message:

Index is out of the bounds of an array.
Parameter name: created
Actual value was 12/31/1969 4:00:00 PM.

Stack Trace:

at Rebex.Net.SftpItem..ctor(String path, String filename, Int64 size, SftpItemType type, DateTime accessed, DateTime modified, DateTime created)
at gbMKS.9h58kZ.ProcessRemoteDirectory(1YiDCIZ traversalInfo, Boolean addNewInfos)
at 1RyBHn.1yALZOZ.cIZv0(1YiDCIZ )
at 1RyBHn.1yALZOZ.N30HDZ()
at 1RyBHn.1yALZOZ.Transfer(YpcDbZ method, 18waHwZ sourceFilter, String targetPath, TransferMethod transferMethod, MoveMode moveMode, LinkProcessingMode actionOnLinks, ActionOnExistingFiles actionOnExistingFiles, 1Acxa2 expectedRootItem)
at gbMKS.9h58kZ.1jMzU7Z(28xx7VZ , p5IYsZ , String , TransferMethod , MoveMode , LinkProcessingMode , ActionOnExistingFiles )
at Rebex.Net.Sftp.1yALZOZ(28xx7VZ , udycp , dpo7FZ , String , TransferMethod , MoveMode , LinkProcessingMode , ActionOnExistingFiles )
at Rebex.Net.Sftp.VGSfy(udycp , String , String , TraversalMode , TransferMethod , MoveMode , LinkProcessingMode , ActionOnExistingFiles , Boolean )
at Rebex.Net.Sftp.18wwkJZ(udycp , String , String , SftpBatchTransferOptions , SftpActionOnExistingFiles )
at Rebex.Net.Sftp.GetFiles(String remotePath, String localDirectoryPath, SftpBatchTransferOptions transferOptions, SftpActionOnExistingFiles existingFileMode)
at sftpExample.Form1.testServer()
Applies to: Rebex SFTP

3 Answers

+1 vote
answered May 2, 2012 by Lukas Pokorny (102,130 points)
edited Jul 12, 2012
 
Best answer

UPDATE: This has been fixed in version 2012 R2

This is caused by a bug in a workaround for servers that return invalid (zero) date/time values (such as FreeFTPd). A hotfix is already available. Please download it from one of these URLs and give it a try:


Rebex SFTP - Hotfix Build 4527 (for .NET 2.0/3.0/3.5/4.0)


Rebex SFTP - Hotfix Build 4527 (for .NET CF 2.0/3.5)

0 votes
answered May 2, 2012 by Mali (320 points)
edited May 3, 2012

@Lukas Pokorny: Thank you. The fix helps when I use Recursive as the SftpBatchTransferOptions to download files. If I use XCopy, it doesn't work as follows:

client.GetFiles(@"/Inbox", @"C:\DataCollection\TestFiles\Download\GrpDownload", SftpBatchTransferOptions.XCopy, SftpActionOnExistingFiles.OverwriteAll);

The function doesn't throw an error, but doesn't the file either.

commented May 2, 2012 by Lukas Matyska (55,430 points)
edited May 2, 2012

I am not sure what you want to download, but if you want to download whole Inbox directory use:

client.Download("/Inbox/*", @"C:\DataCollection\TestFiles\Download\GrpDownload",
    TraversalMode.Recursive, TransferMethod.Copy, ActionOnExistingFiles.OverwriteAll);

If you want to download only .txt files use:

client.Download("/Inbox/*.txt", @"C:\DataCollection\TestFiles\Download\GrpDownload",
    TraversalMode.MatchFilesDeep, TransferMethod.Copy, ActionOnExistingFiles.OverwriteAll);
commented May 3, 2012 by Mali (320 points)
edited May 3, 2012

Thank you. This solution worked as well. A couple of questions: 1. I notice that the download option doesn't preserve the Write Time of the file. Is that true? Is there any way that I can specify the download to retain the timestamp of the original file?

  1. Will this method work for subdirectories as well? I am unable to test this with my company's SFTP server as IT is still working on granting me privileges to perform the operation.

And, on a completely different note, I am also just curious to know how the XCopy batch trasfer operation differs from Recursive option when we use GetFiles.

+1 vote
answered May 3, 2012 by Lukas Matyska (55,430 points)
edited May 7, 2012

The GetFiles method is considered as old API, but it is still available. The desired methods to use are Download and Upload. Please see this forum post.

The XCopy mode is equivalent to TraversalMode.MatchFilesDeep in new API.

The Recursive mode is intended to be used to download whole directory recursively, while the MatchFilesDeep (XCopy) is intended to be used to download only specific files from a directory and its subdirectories.

E.g. typical scenarios are: Download("/Inbox", Recursive); Download("/Inbox/*.txt", MatchFilesDeep);

The improved documentation (not in public release yet) describes the two enums as follows:

Recursive:

Performs SHALLOW search for files and directories; do RECURSIVE transfer of matching directories.
Shallow search means that items are searched only in the first level of given directory.
If the pattern matches a file, the file is processed.
If the pattern matches a directory, all files and subdirectories are processed.
MatchFilesDeep:
Performs DEEP search for files only. This is like DOS xcopy deep file search.
Deep search means that files are searched in the given directory and also in all its subdirectories.

In the current version Write Time is not persisted, but it can be useful feature. We will add a support for this in one of the future releases. In the meantime you can register the BatchTransferProgress event. If the e.Operation = FileTransferred you can update Write Time manually using the e.CurrentFileModified property.

commented May 7, 2012 by Mali (320 points)
edited May 7, 2012

@Lukas Matyska: Thank you for the prompt response.

...