2003-10-05 06:29:47 PM I am not being able to get the size of the file being downloaded through TIdFTP. AWorkCountMax always returns 0 and the program freezes at the size request. I have done this: If AWorkCountMax = 0 then ProgressBar1.Max:= idFTP.Size(FileName) else ProgressBar1.Max:= AWorkCountMax; The 'FileName' variable is the same previously defined to be used in idFTP.Get(FileName, DestFolder + FileName, true, true); I am using D5 and Indy 9.0.14.
First, your method of getting the file size is extremely slow, especially if you're going to be using this to list a lot of files. Style Works 2000 Universal Com Serial Number. You're actually opening the file, moving the file pointer to the end of the file to get the size, and then closing the file. Also, this may fail if the file is open by another application exclusively.
What may be wrong? Marcio Ehrlich.
Quote I am not being able to get the size of the file being downloaded through TIdFTP. AWorkCountMax always returns 0 and the program freezes at the size request. I have done this: If AWorkCountMax = 0 then ProgressBar1.Max:= idFTP.Size(FileName) else ProgressBar1.Max:= AWorkCountMax; The 'FileName' variable is the same previously defined to be used in idFTP.Get(FileName, DestFolder + FileName, true, true); I am using D5 and Indy 9.0.14.
What may be wrong? Marcio Ehrlich It is probaly connected with FTP serwer type. Not all serwers have this information. Quote I have done this: If AWorkCountMax = 0 then ProgressBar1.Max:= idFTP. Dompdf Install New Fonts On Windows. Size(FileName) You cannot call Size() in the context of the OnWork. TIdFTP is already busy doing something else, you will corrupt the data stream by sending a command and waiting for a response in the middle of another command/response that is already in progress.
You need to call Size() *before* calling Get(): ProgressBar1.Max:= idFTP.Size(FileName) idFTP.Get(FileName, DestFolder + FileName, true, true); For FTP, AWorkCountMax will always be 0, so there's no need to test for it inside the OnWorkBegin event. Quote That article doesn't even use the AWorkCountMax for progress tracking. It is used only to test a separate FileSize variable that was assigned elsewhere. If AWorkCountMax is less than the FileSize than the FileSize variable is adjusted accordingly. Since AWorkCountMax is always 0 for a download, the FileSize variable is left untouched.
If you read the article more carefully, you will see that the FileSize variable is always assigned to the return value of TIdFTP::Size() *prior* to calling TIdFTP::Get(). And then that FileSize variable, not the AWorkCountMax, is used for the progress tracking. That is the correct way to handle it.
Quote Ok., I can access the article now. That discussion is suggesting an approach that is similar to what the third article you listed is doing. It is obtaining the file size prior to calling Get(), it does not use the AWorkCountMax value at all. They call TIdFTP::Size() first, and if it fails then they use TIdFTP::List() and parse the Size out of the returned listing, either way calling TIdFTP::Get() only after the FileSize has already been obtained. I do not know what 'JIA_Remy' was thinking about at the end of the discussion, AWorkCountMax is never valid for a download. What he claimed will only work for uploads, not downloads.
You can verify that for yourself by just looking at the TIdFTP source code. TIdFTP::Get() eventually calls TIdTCPConnection::ReadStream() for the actual transfer.
It calls it like this: ReadStream(ADest, -1, True); TIdTCPConnection::ReadStream() then does the following: procedure TIdTCPConnection.ReadStream(AStream: TStream; AByteCount: Integer = -1; const AReadUntilDisconnect: Boolean = False). If AReadUntilDisconnect then begin.
BeginWork(wmRead); end else begin. BeginWork(wmRead, LWorkCount); end. End; As you can see, the AReadUntilDisconnect parameter is set to true, which causes BeginWork() (the method that triggers the OnWorkBegin event handler) with no AWorkCountMax value at all, thus the reason why it is always 0 for downloads. There *may* be additional problems, depending on the server, as others have hinted. Even if you call TidFTP.size before 'get', it may return 0 on some servers.
I met this problem on Sun Solaris 8 - my app progress bar would work fine with an PC/ICS server and with HP boxes, but 'size' always returned 0 on the Sun. Support for Solaris format has probably been added in the later vrsions of Indy, but the same problem may turn up with some other OS/server. For these cases where 0 was returned, I had to resort to leaving the bar at 0% until the get was done, then setting it to 100%.
Rgds, Martin. Quote There *may* be additional problems, depending on the server, as others have hinted. Even if you call TidFTP.size before 'get', it may return 0 on some servers. Not all servers implement the SIZE command. Hense the one article's approach to parse the directory listing for a given file when Size() fails. Those are the only two ways to get a file's size. However, even the directory listing may not specify a file size at all, or at least not an accurate one.
It depends on the capabilities of the actual OS/filesystem which the server is running on. There are known OS/filesystem setups that do not support file sizes in a coherent fashion.
The latest version of Indy does try its best to handle those setups, though. Quote For these cases where 0 was returned, I had to resort to leaving the bar at 0% until the get was done, then setting it to 100%. The alternative would be to not use a ProgressBar at all, but a StatusBar or Label instead, displaying a running byte count from the OnWork event instead of a percentage. At least then the user can still see that bytes are being transferred, just the total number of received bytes rather than a 1-100 percentage since the total size is unknown beforehand.