B4J Question [Solved] I have an issue with File.CopyAsync

John Naylor

Active Member
Licensed User
Longtime User
Hey all!

Please note this is NOT an ABMaterial issue!

I have two systems running on a VPS. One is an ABMaterial app which uses the ABFileManager system and another is a light weight B4J webapp. The two systems need to share data (images) so I have set up a folder that both systems can access. Great so far and it works apart from one particular part.

To be able to display an image in the light webapp I need to copy it from the shared folder into a temp folder under www. Otherwise a browser can't access the file.

Here's my issue - the following code works a treat...

Using File.Copy:
Sub btnGet_Click (Params As Map)        'When the display image button is clicked.....
   
    Dim ft1 As Future = text1.GetVal            'Get the text box value

    Result.SetText("Getting photo : " & (ft1.Value)) 'Set the result param (a label) to "Getting Photo: " + whatever was typed
   
    Dim ext As String = GetExtension(ft1.Value)        'Find the file extension (probably .jpg)
   
    File.Copy("/home/domain/fdata/FileManager/photostore/", ft1.Value & ext, "/home/domain/lightapp.domain.co.uk/www/temp/", ft1.Value & ext)
   
    Dim img As String = "<img src=""/temp/" & ft1.Value & ext & """ alt="""" width=""1200"" height=""800""> "    'Build an img html tag
   
    Log ("img = " & img)
    ImageToShow.Sethtml (img)    'Set the tag in the html code to our new one
    Log ("Image Set")
   
End Sub

All well and good but I am concerned that simply using copy will cause issues if a lot of people are accessing photos like this.

As such I tried using the following -


Using File.CopyAsync with wait for:
Sub btnGet_Click (Params As Map)        'When the display image button is clicked.....
   
    Dim ft1 As Future = text1.GetVal            'Get the text box value

    Result.SetText("Getting photo : " & (ft1.Value)) 'Set the result param (a label) to "Getting Photo: " + whatever was typed
   
    Dim ext As String = GetExtension(ft1.Value)        'Find the file extension (probably .jpg)
   
    Wait For (File.CopyAsync("/home/domain/fdata/FileManager/photostore/", ft1.Value & ext, "/home/domain/lightapp.domain.co.uk/www/temp/", ft1.Value & ext)) Complete (Success As Boolean)
    Log("Success: " & Success)
   
    If Success Then
        Dim img As String = "<img src=""/temp/" & ft1.Value & ext & """ alt="""" width=""1200"" height=""800""> "    'Build an img html tag
   
        Log ("img = " & img)
        ImageToShow.Sethtml (img)    'Set the tag in the html code to our new one
        Log ("Image Set")

    End If
   
End Sub

This doesn't work as expected. The file does get copied into the temp folder however it no longer displays on screen. Even testing using a sleep(5000) before setting ImageToShow makes no difference. If I click the button again after a few seconds the image does show up (because it's already in the temp folder??).

I was under the impression that using the Wait.For would be the most sensible option.

Hints at what I'm doing wrong would be greatly appreciated!
 
Last edited:

EnriqueGonzalez

Well-Known Member
Licensed User
Longtime User
This is not working because the wait for is essentially calling a return on that function. That means that it is not calling anything below line 10 until much

copy will cause issues if a lot of people are accessing photos like this.

Well yes, may be checking if the image is already there could help.

Usually, and some other expert could proof me wrong, but you should not access resources outside the server environment (say the disk drive) in the same thread that you are using to communicate with the user.

Best approach should be to have background threads copying the files from one side to the other.

Or if you have other ways to communicate with the user, then use callsubdelayed on a shared module and let tHe main thread handle the copy part.
 
Upvote 1
Cookies are required to use this site. You must accept them to continue using the site. Learn more…