Android Question FTP - how to wait till file is downloaded?

MoraviaVenus

Member
Licensed User
Longtime User
Hi community,

I am struggling one week already with the problem, how to handle the end of FTP download process.

I have code like this, where I just download file and read first line of it.

B4X:
Sub Activity_Create(FirstTime As Boolean)

    storage = File.DirRootExternal
    FTP.Initialize("FTP", FTPServer, 21, "UserName", "Password")   

    TheDownloadFunction

End Sub

Sub TheDownloadFunction

    Dim content as String
    Dim del as Boolean

    {some code...}

    ProgressDialogShow("Downloading file...")

    DownloadSelectedFile

    txtReader.Initialize(File.OpenInput(storage, downloadedFile))
    content = txtReader.ReadLine
    txtReader.Close

    del = File.Delete(storage, downloadedFile)

End Sub

Sub DownloadSelectedFile()
  
    FTP.DownloadFile(ftpFolder & downloadedFile, False, storage, downloadedFile)
  
End Sub

Sub FTP_DownloadProgress (ServerPath As String, TotalDownloaded As Long, Total As Long)
  
    Dim str As String
    str = "Downloaded " & Round(TotalDownloaded / 1000) & " kB"
  
    If Total > 0 Then str = str & " out of " & Round(Total / 1000) & "KB"
    Log(str)
  
End Sub

Sub FTP_DownloadCompleted (ServerPath As String, Success As Boolean)

    ProgressDialogHide
  
End Sub

Now, when function
B4X:
DownloadSelectedFile
is called, code immediately goes ahead and executes next line
B4X:
txtReader.Initialize(File.OpenInput(storage, downloadedFile))
and consequently next line
B4X:
content = txtReader.ReadLine
, where it crashes with error message: java.io.FileNotFoundException: ... open failed: ENOENT (No such file or directory). It seems to me, that just after that, the requested file is downloaded and available for reading...

Please, how can I force the code to wait till the file is downloaded and just afterwards to run ahead?

BTW, another problem, variable "del" is True after executing File.Delete(storage, downloadedFile) and deleting downloadedFile, but, the file is still in storage directory... Any ideas why?

Thank you
 
Last edited:

DonManfred

Expert
Licensed User
Longtime User
Have a look at this example. It may of help.

Instead of multiple files you just download one...
 
Upvote 0

MoraviaVenus

Member
Licensed User
Longtime User
Hi DonManfred,

thank you for hint. I checked your code and I see, that command FTP.DownloadFile is the last command in Activity_Create, and when your download finishes successfully, you process the rest of code in Sub FTP_DownloadCompleted. On the other hand, in my code, after the download finishes, the code in parent procedure continues...

Is my logic of code basicly wrong? Should I always handle the dependent code inside of Sub FTP_DownloadCompleted?

FYI, I use Sub DownloadSelectedFile() from 4 different places, with different file names and different purpose (so handling the dependent code inside of Sub FTP_DownloadCompleted is a complication for me).

Thank you.
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
On the other hand, in my code, after the download finishes, the code in parent procedure continues...

No, that´s wrong. You START the download; which is asynchronous btw...
The code following
B4X:
 DownloadSelectedFile
is executed imediatly after STARTING the download. Usually the download is not finished at this moment... You need to overthink your strategy.

Start the download and wait for the download to finish.

Is my logic of code basicly wrong? Should I always handle the dependent code inside of Sub FTP_DownloadCompleted?

It must NOT directly inside this sub. you could create a sub for the work which should be done after downloading.

B4X:
sub todoafterdownload
    txtReader.Initialize(File.OpenInput(storage, downloadedFile))
    content = txtReader.ReadLine
    txtReader.Close
    del = File.Delete(storage, downloadedFile)
end sub
and then just call
B4X:
todoafterdownload
when download is finished from
B4X:
FTP_DownloadCompleted

FYI, I use Sub DownloadSelectedFile() from 4 different places, with different file names and different purpose (so handling the dependent code inside of Sub FTP_DownloadCompleted is a complication for me).

You must keep in mind that downloads are asynchronous (like httputils jobs)
 
Upvote 0
Top