Our Products:   CompleteFTP  edtFTPnet/Free  edtFTPnet/PRO  edtFTPj/Free  edtFTPj/PRO
0 votes
in FAQ: edtFTPnet/PRO by (190 points)
I am using version with .NET 3.5 and try to use the DownloadStream method to process a file on an FTP server.
I define dataStream=MemoryStream(10000) and assign BytesTransferred to a method receiving BytesTransferredEventArgs.

I use an FtpConection instance (ftpClient).

If the file to access is small, ftpClient.DownloadStream(dataStream,filename) returns successfully, and the stream is available and processable.

However, if the file is big, the same call hangs forever, and no call to the BytesTransferred delegate is done.

filename IS in the current folder on the FTP server.

What do I miss here?
by (158k points)
What happens if you use a FileStream?
by (190 points)
The same, I guess. I tried with a DownloadByteArray and got the same problem. It turns out that DownloadStream is working fine as long as I do not add a BytesTransferred handler.
If I do, the Download method hangs indefinitely if the file to transfer is large.
Maybe I use BytesTranferredHandler in a wrong way...
by (158k points)
Interesting. Maybe post a minimal code snippet that shows the issue.
by (190 points)
Briefly this is what I do:
All FTP actions are carried out in a separate thread.
After doing some CWD and file listing with the FTPConnection instance (ftpClient), I do the following:
ftpClient.BytesTransferred += OnBytesTransferred;

dataStream is a MemoryStream with capacity 10000.
FileName is a valid file name in the current working directory.
Size of file is 31.7 MB
there is a lock around ftpClient.BytesTransferred+=... and ftpClient.DownloadStream.
I have put a try-catch around it all.
No exceptions thrown, only hang.

Method listing:
        protected override void ProcessFtpFileRequest(IFtpConnection ftpClient, FtpSession.ReportProgress progressReporter)
            // Call base first.
            base.ProcessFtpFileRequest(ftpClient, progressReporter);


                var dataStream = WritableStream;
                _fileSize = !SimpleMode ? ftpClient.GetSize(FileName) : 1024;

                if (dataStream == null) return;

                if (progressReporter != null)
                    progressReporter.Invoke(FileName, 0, 0);
                lock (dataStream)
                    ProgressReporter = progressReporter;
                    var cwd = ftpClient.ServerDirectory;
                    ftpClient.BytesTransferred += OnBytesTransferred;

                    ftpClient.DownloadStream(dataStream, FileName);

            catch (FTPException e)
                DiagLog.ErrorFormat("{0} download error {1} ({2})", FileName, e.Message, e.ReplyCode);
                FtpResult = e.ReplyCode == 550 ? FtpBackgroundWorkerResult.FileNotFound : FtpBackgroundWorkerResult.FileTransferFailed;
            catch (IOException ioe)
                DiagLog.ErrorFormat("{0} download IOException {1}", FileName, ioe.Message);
                FtpResult = FtpBackgroundWorkerResult.FileTransferFailed;
                // Remember to remove event listner so FTP connection can be
                // properly garbaged collected.
                ftpClient.BytesTransferred -= OnBytesTransferred;
                var res = FriendlyFtpResult(FtpResult);
                DiagLog.DebugFormat("{0} {1} ({2} bytes)", string.IsNullOrEmpty(res) ? "Downloaded" : "Failed to download", FileName, _fileSize);
                ProgressReporter = null;

ftpClient is of type IFtpConnection. The implementation of this interface inherits FTPConnection or SecureFTPConnection, and the interface will give access to all methods of FTPConnection or SecureFTPConnection as if they were directly addressed.

At least, that is my idea.
by (190 points)
The OnBytesTransferred method never gets called and no exception is caught.

If I comment out the event handler assignment, DownloadStream finishes after some seconds.
by (190 points)
- and removing the lock(dataStream) has no positive effect.

Please log in or register to answer this question.