Android Tutorial Android FTP tutorial

Status
Not open for further replies.
Old and irrelevant tutorial. Follow this one instead: [B4X] Net library (FTP, SMTP, POP) with Wait For

This tutorial covers the FTP object which is part of the Net library.
The Net library is based on Apache Commons Net.

Android OS doesn't allow us, the developers, to block the main thread for more than 5 seconds. When the main thread is busy for too long and is not able to handle the user events the "Application not responding" dialog appears.
Therefore slow operations like network operations should be done in the background.
The FTP library is built in such a way. All of the methods return immediately. When a task completes an event is raised. In fact you can submit several tasks one after another. The FTP protocol supports a single task at a time so the tasks will be processed serially.

Using the FTP library is pretty simple.
The first step is to initialize the FTP object. If this is an Activity module then you should do it in Activity_Create when FirstTime is true.
For Service modules it should be initialized in Service_Create.
B4X:
Sub Process_Globals
    Dim FTP As FTP
End Sub
Sub Globals

End Sub

Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        FTP.Initialize("FTP", "ftp.example.com", 21, "user", "password")
    End If
FTP.Initialize doesn't connect to the server. Connection will be established implicitly together with the next task.

Download

Downloading a file is done by calling DownloadFile with the remote file path and the local file path.
If you want to show the download progress then you should handle DownloadProgress event.
When download completes the DownloadCompleted event is raised. The ServerPath is passed as the first parameter to all events. You can use it to distinguish between different tasks. Make sure to check the Success parameter. If Success is False then you can find the exception message by calling LastException.

B4X:
    FTP.DownloadFile("/somefolder/files/1.zip", False, File.DirRootExternal, "1.zip")
   
Sub FTP_DownloadProgress (ServerPath As String, TotalDownloaded As Long, Total As Long)
    Dim s As String
    s = "Downloaded " & Round(TotalDownloaded / 1000) & "KB"
    If Total > 0 Then s = s & " out of " & Round(Total / 1000) & "KB"
    Log(s)
End Sub

Sub FTP_DownloadCompleted (ServerPath As String, Success As Boolean)
    Log(ServerPath & ", Success=" & Success)
    If Success = False Then Log(LastException.Message)
End Sub
Upload

Uploading is similar to downloading.
B4X:
    FTP.UploadFile(File.DirRootExternal, "1.txt", True, "/somefolder/files/1.txt")

Sub FTP_UploadProgress (ServerPath As String, TotalUploaded As Long, Total As Long)
    Dim s As String
    s = "Uploaded " & Round(TotalUploaded / 1000) & "KB"
    If Total > 0 Then s = s & " out of " & Round(Total / 1000) & "KB"
    Log(s)
End Sub

Sub FTP_UploadCompleted (ServerPath As String, Success As Boolean)
    Log(ServerPath & ", Success=" & Success)
    If Success = False Then Log(LastException.Message)
End Sub
List files and folders

FTP.List sends a request for the list of files and folders in a specific path.
The ListCompleted event is raised when the data is available.
You can use code similar to the following code to get more information on the entries:
B4X:
FTP.List("/")
...
Sub FTP_ListCompleted (ServerPath As String, Success As Boolean, Folders() As FTPEntry, Files() As FTPEntry)
    Log(ServerPath)
    If Success = False Then
        Log(LastException)
    Else
        For i = 0 To Folders.Length - 1
            Log(Folders(i).Name)
        Next
        For i = 0 To Files.Length - 1
            Log(Files(i).Name & ", " & Files(i).Size & ", " & DateTime.Date(Files(i).Timestamp))
        Next
    End If
End Sub
Delete
Delete is done by calling FTP.Delete with the full path. Again an event will be raised when the task completes (DeleteCompleted).

Closing the connection
You can close the connection by calling FTP.Close. Close will wait for the other tasks to complete and then will close the connection. This happens in the background.
FTP.CloseNow will immediately close the connection, failing the remaining tasks.

Some notes:
- At any given time there should be less than 15 waiting tasks. Otherwise you will get a RejectedExecutionException (this happens when the internal threads pool is exhausted).
- The order of the completed tasks may be different than the order of submission.
- The AsciiFile parameters sets the file transfer mode. If AsciiFile is true then every occurrence of an end of line character will be translated based on the server native end of line character. If your FTP server is Unix or Linux then the end of line character is the same as Android.
In most cases you can set AsciiFile to false.

The library is available for download here: http://www.b4x.com/forum/additional...92-new-net-library-android-ftp-smtp-pop3.html
 
Last edited:

refsmmat

Member
Licensed User
Longtime User
FTP upload - append file on server

Hello Erel et al,

Many thanks for the development work on the NET library. I have found it very easy to use.

Is it possible to use it to append an existing text file on an ftp server?

Rather than upload a file, I would like to be able to just send the new data (ASCII) to add a line to the file.

I understand I have the option to download the file and append it on the Android device, but over time, as the file grows, this will introduce other complications.

Thanks for your advice.

Regards,

REFSMMAT
 

wl

Well-Known Member
Licensed User
Longtime User
The FTP protocol does not support this option.

Your only option is to write a HTTP page or webservice to which you can send the new lines. The HTTP page can then append these lines to an existing file.
 

refsmmat

Member
Licensed User
Longtime User
The FTP protocol does not support this option.

Your only option is to write a HTTP page or webservice to which you can send the new lines. The HTTP page can then append these lines to an existing file.

Hi WL, thanks for the response.

The reason I asked the question is I am currently performing this ftp file append operation using Arduino with a GPRS modem.
(AT+FTPPUTOPT=APPE). The ftp server is nothing special, but it does accept appending of files on the server.

The limitation is I am not uploading a file, but rather the bytes to append the existing file on the ftp server. This doesn't bother me as it suited my application.

I am switching this activity from Arduino to an Android device to get more capability in other areas. Losing the append function is a small price to pay.

Thanks again.
Regards,
REFSMMAT
 

refsmmat

Member
Licensed User
Longtime User
The FTP protocol does not support this option.

Your only option is to write a HTTP page or webservice to which you can send the new lines. The HTTP page can then append these lines to an existing file.
Hi WL, thanks for the response.

The reason I asked the question is I am currently performing this ftp file append operation using Arduino with a GPRS modem.
(AT+FTPPUTOPT=APPE). The ftp server is nothing special, but it does accept appending of files on the server.

The limitation is I am not uploading a file, but rather the bytes to append the existing file on the ftp server. This doesn't bother me as it suited my application.

I am switching this activity from Arduino to an Android device to get more capability in other areas. Losing the append function is a small price to pay.

Thanks again.
Regards,
REFSMMAT
 

wl

Well-Known Member
Licensed User
Longtime User
Just to be clear:

Although FTP does not standard support this, you could decide to write your own FTP server (in .NET for example there are a few good libraries for this) that would receive your files and append it.

But that would not be a standard FTP server, so I would stick to the HTTP upload as stated before.
 

rfresh

Well-Known Member
Licensed User
Longtime User
Is SFTP supported yet and if not, do you know when it might be? There are heavy mandates on eCommerce websites for PCI compliance and one of requirements is SFTP access only. I need SFTP capability in the FTP tool that I want to build using your product. Without SFTP there is no need for me to use your product. Thanks.

I was able to make this Post but now I can't post replies.

I found this free java SFTP Lib at http://www.zehon.com/index.html

Are we able to make use of this kind of lib?
 
Last edited:

AscySoft

Active Member
Licensed User
Longtime User
Is SFTP supported yet and if not, do you know when it might be? There are heavy mandates on eCommerce websites for PCI compliance and one of requirements is SFTP access only. I need SFTP capability in the FTP tool that I want to build using your product. Without SFTP there is no need for me to use your product. Thanks.

As far as I know, there isn't and I really don't know if/when this 'feature' will become available. I was searching too for this protocol, but I manage to do some encrypted files and then I sent them over FTP as usual. But this was in my case.
Sorry for my (Johnny) English!

see my question fist page of this thread!
 
Last edited:

refsmmat

Member
Licensed User
Longtime User
Just to be clear:

Although FTP does not standard support this, you could decide to write your own FTP server (in .NET for example there are a few good libraries for this) that would receive your files and append it.

But that would not be a standard FTP server, so I would stick to the HTTP upload as stated before.

Ok - thanks.

Regards,
Stephen
 

Vinians2006

Active Member
Licensed User
Longtime User
Where should I put the Close method ? Im using a List object that hold all files that I want to download. So I have a FOR loop to handle this task. How can I know if was an error and abort the for loop ? And how about Pause and Resume in tha activity ? Please make a complete example for us.
Thanks!
 

Vinians2006

Active Member
Licensed User
Longtime User
It is better to have a list and then download the files one after another. When one file completes you should remove it from the list and start the next download.
hum.. ok I will try. Another question is that I was trying to create a "code module" especilist in donwload and upload a file easly but it seems that the FTP object only works in a Activity module ?
Thanks in advance!
 

biometrics

Active Member
Licensed User
Longtime User
Hi Erel,

I am converting our exiting application from the old FTP library to the new one. I notice the big difference being that the old one was procedural function calls vs the new one being event driven.

We have a large code module I need to convert that is procedural based and rewriting it to be purely event driven would be a massive job. I was hoping to achieve the same effect as follows:

B4X:
Sub Process_Globals
    Dim libFTP As FTP
    Dim bCommandSuccessful As Boolean
    Dim sFtpServer As String
    Dim sFtpUsername As String
    Dim sFtpPassword As String
    Dim sFtpDirectory As String
End Sub

Sub Activity_Create(FirstTime As Boolean)
    libFTP.Initialize("libFTP", sFtpServer, 21, sFtpUsername, sFtpPassword)
    FTPList
End Sub

Sub FTPList()
    bCommandCompleted = False
    libFTP.List(sFtpDirectory)
    Do Until bCommandCompleted
        DoEvents
    Loop
End Sub

Sub libFTP_ListCompleted(ServerPath As String, Success As Boolean, Folders() As FTPEntry, Files() As FTPEntry)
    bCommandCompleted = True
End Sub

But it seems the event won't fire unless I do a Return out of the FTPList Sub. Doing the Do/DoEvents/Loop stops the event from firing.

How can I do this?
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
The FTP operations must be event driven. Otherwise they will block the main thread and will crash the application.

You cannot use such a loop. DoEvents will only process UI related messages.
You should instead use a global variable to handle the state and continue the program flow when the download completes.
This is a bit more complicated but it is the only correct way to build it.
 
Status
Not open for further replies.
Top