Question
Michael Derr · Apr 6, 2020

Confirming file size after SFTP PutStream

Hello!

 

This may seem a bit strange, but I'd like to make a business operation which would put a file via SFTP and then confirm that the filesize on the remote server is consistent with expectations.  I am thinking either of a custom copy or extension of the adapter (right now it is using EnsLib.FTP.OutboundAdapter) that overwrites method PutStream, or a version of the FTP.PassThroughOperation with a customized method OnMessage that does the check after the PutStream completes OK-- but I am uncertain of how exactly to modify either method to make the check.  What functions could I even call to check the remote filesize agaisnt the size of the file that was just put to the stream?  Even a pointer to the appropriate part of the documentation would be helpful.  Right now I'm just floundering about in the entries for FileListFetch, etc.

Thanks!

Michael

 

 

10
4 0 7 402
Log in or sign up to continue

Replies

Hi Michael,

I assume you were looking at the %Library.File documentation for FileListFetch. FileListFetch is not meant to be used directly, but is a part of a class query which can be used as documented here:

Defining and Using Class Queries

https://cedocs.intersystems.com/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&LIBRARY=%25SYS&CLASSNAME=%25Library.File

If you can navigate to the directory then you could use ##class(%Library.File).GetFileSize(), however for a remote FTP server this probably wouldn't work. You would want to use %Net.SSH.SFTP as documented here:

Using SSH

https://cedocs.intersystems.com/latest/csp/documatic/%25CSP.Documatic.cls?APP=1&CLASSNAME=%25Net.SSH.SFTP

edit: the FileList query is not in %Library.File - I am not sure where that query comes from but the rest of my post remains revelant

FileList was likely found in the EnsLib.FTP.Common class reference. This is the class extended by EnsLib.FTP.OutboundAdapter. I suspect that could work also - see above documented syntax for running the query.

Hope that helps!

To get the remote filesize over SFTP you would use the FileInfo method in %Net.SSH.SFTP.

To get the stream size you would use the SizeGet method on the stream.

However, be aware that during the transfer, depending on OS and methods used there may be translations of line terminators which would affect file size (often called ASCII mode).  This is not very common in SFTP, unlike standard FTP, but can still occur.  Also, I have found in the past that on a non-file stream the SizeGet is not always the same as the final file size when saved but that might just be my findings in special cases.

Thanks, this is helpful...  I am fairly new to objectscript, so I'm having some difficulty retrieving the filesize from FileInfo from within the customized adapter.  I think I need to call it after a session has been established, and so I'm trying:

Set tFileInfoList=$LISTBUILD("test","test")

do ..%sftpSession.FileInfo(pFilename,.tFileInfoList)

Set tFinalSize= $LIST(tFileInfoList,2)

But this results in an error, ERROR <Ens>ErrException: <UNDEFINED>zPutStream+10^ACH.OutboundAdapterSFTPConfirm.1 *tFileInfoList -- logged as '-' number - @' Set tFinalSize= $LIST(tFileInfoList,2)'

Looking for any info on this error is unproductive.  I must be misunderstanding something about how ByRef arguments work-- likely I am misunderstanding how to invoke FileInfo and handling %List objects for this particular session instance, as well.

I'd recommend capturing the status value returned by FileInfo() -- it's possible that the call is failing.

set tSC=..%sftpSession.FileInfo(pFilename,.tFileInfoList)
if $$$ISERR(tSC) {
    // There was an error, do something
}

Yeah, that's a good call.  I went ahead a nd did this and am indeed getting a No Such File error.  I'll dig some more.

Thanks again!

Turns out that it needed the remote filepath.  After I added that in, this appears to work without error.  I'll try to be more mindful of capturing and evaluating errors!