GetFile and Event FileTransferred not working?

Advertisement

jaysplus
Joined:
Posts:
5

GetFile and Event FileTransferred not working?

I didn't get any FileTransferred events from using GetFile() (note, not GetFiles - just GetFiles because I need it to go into a stream).
According to the documentation this should trigger an event.
Not sure if the file sizes have anything to do with this issue - the files I'm transferring are very small ~ 1–2KB, and yes, I'm on SFTP.

The breakpoint at WinSCPFileTransferred never gets triggered despite files being downloaded and transferred successfully.

My code is as follows:
public bool FetchFiles()
{
    SendMsg = false;
 
    try
    {
        if (!SetConnectionParameters())
        {
            nlog.Error("FTPService: Failed configuring Session Parameters for {name}", currEntity.name);
            return false;
        }
 
        using (Session session = new Session())
        {
            session.ExecutablePath = Path.Combine(CurrContext.FunctionAppDirectory, "winscp.exe");
            session.DebugLogPath = null; //Null means no log path (Path to store assembly debug log)
            session.SessionLogPath = null//Null means no log path (Path to store session log path)
            session.FileTransferred += WinSCPFileTransferred;
            try
            {
                if (!session.Opened)
                {
                    session.Open(sessionOptions);
                }
 
                var transferOptions = new TransferOptions
                {
                    TransferMode = TransferMode.Binary,
                    OverwriteMode = OverwriteMode.Overwrite,
                };
 
                nlog.Info("FTPService: Session Open for {name}. About to Get files", currEntity.name);
                GetFilesAndUploadAsync(session);
            }
            catch (Exception ex)
            {
                nlog.Error(ex, "FTPService: Exception Opening Session Parameters for {name}.", currEntity.name);
                return false;
            }
        }
    }
    catch (Exception ex)
    {
        nlog.Error(ex);
        return false;
    }
    return true;
}
 
 
private void GetFilesAndUploadAsync(Session conn)
{
    try
    {
        string filePath = null;
 
        //Get a List of Files in Directory - seems to be +1 of the actual file count...
        RemoteDirectoryInfo directory = conn.ListDirectory(currEntity.remotefolder);
        Stream stream;
        nlog.Debug("Number of files in remote directory:{count}",directory.Files.Count-1);
        foreach (RemoteFileInfo fileInfo in directory.Files)
        {
            if (!fileInfo.Name.Equals(".") & !fileInfo.Name.Equals(".."))
            {
                nlog.Debug(
                    "{0} with size {1}, permissions {2} and last modification at {3}",
                    fileInfo.Name, fileInfo.Length, fileInfo.FilePermissions,
                    fileInfo.LastWriteTime);
 
                filePath = currEntity.remotefolder + "/" + fileInfo.Name;
 
                //only supported for SFTP - otherwise will throw exception!
                //GetFile/Putfile from WinSCP returns a custom and very limited implementation of Stream. 
                //it CANNOT be seeked i.e. SetLength/Position not allowed
                stream = conn.GetFile(filePath); 
 
                if (PushFileToAzureBlobContainer(stream, fileInfo.Name))
                {
                    try
                    {
                        stream.Dispose();
                        conn.RemoveFile(filePath);
                    }
                    catch (Exception ex)
                    {
                        nlog.Error(ex, "FTPService: Exception removing file {filename} from remote directory for {name}.", fileInfo.Name, currEntity.name);
                    }
                }
                stream.Dispose();
            }
        }
    }
    catch (Exception ex)
    {
        nlog.Error(ex, "FTPService: Exception listing remote directory for {name}.", currEntity.name);
    }
}

Reply with quote

Advertisement

martin
Site Admin
martin avatar
Joined:
Posts:
41,450
Location:
Prague, Czechia

Re: GetFile and Event FileTransferred not working?

Indeed, it is not. But what would it be good for anyway? The point of the event is to get notified about individual files of a batch transfer (like with Session.GetFiles). But you are transferring a single file. You know, what is it. You know, when does the transfer finish.

Reply with quote

jaysplus
Joined:
Posts:
5

Re: GetFile and Event FileTransferred not working?

Hi Martin
Maybe I misunderstand the API.
What happens in the return of the function? Does it mean the file already fully uploaded when the function returns?
or does GetFile return instantly and since there is no event, I need to manually check the file?

From my testing, it seemed that GetFile returns before the file is fully uploaded, because if I dispose and start processing another file, I end up with alot of 0KB files - hence my interest in waiting for the event.

Reply with quote

martin
Site Admin
martin avatar

Re: GetFile and Event FileTransferred not working?

1) Session.GetFile downloads a file. It does not upload.
2) It returns quickly (not immediately), but definitely before the download finishes. You have to read the returned Stream to complete the download.

Reply with quote

jaysplus
Joined:
Posts:
5

Re: GetFile and Event FileTransferred not working?

Hi Martin
Thanks again for responding. Sorry for the confusion when I typed above about GetFile and uploads - yes I'm aware it's for downloading, just typed the wrong words.

In terms of checking the stream, are you suggesting I have to compare the stream length against FileInfo.Length to know if the file is fully downloaded?

Thanks
Jay

Reply with quote

Advertisement

martin
Site Admin
martin avatar

Re: GetFile and Event FileTransferred not working?

I do not understand. You do not need to check anything. Just read the stream to the end. That's what I assume the PushFileToAzureBlobContainer does. Once you read the stream to the end, you know the download has finished. To be honest, I do not really understand, what are you trying to achieve or what your problem is. Maybe you actually do not have any.

Reply with quote

jaysplus
Joined:
Posts:
5

Re: GetFile and Event FileTransferred not working?

Hi Martin
Thanks – after some experimentation, I realize the stream.Read() is actually blocking until it's complete i.e. does not return until it ends.
So I don't have a problem anymore since I know I can rely on this method, it just wasn't clear to me that's how the API should be used from the documentation.

Reply with quote

martin
Site Admin
martin avatar
Joined:
Posts:
41,450
Location:
Prague, Czechia

Re: GetFile and Event FileTransferred not working?

Yes, Stream.Read is blocking. That's by the definition of the Stream .NET interface. See https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.read
No need to document it explicitly for WinSCP implementation.
Though that's not the same as "return until it ends". It might return earlier. You have to call it repeatedly, until it returns 0.

Reply with quote

Advertisement

You can post new topics in this forum