Android Question Title: File.Exists returns True for a file that does not exist

Roberto_Barbato

New Member
Hello,

I have encountered a strange behavior with <span>File.Exists</span> in B4A on an Android tablet.

My images folder is:

<span>/storage/emulated/0/Pictures/RMenu/Images/Plu</span>

The folder contains only the following file:

<span>CocaCola.jpg</span>

I verified this using <span>File.ListFiles</span>, which returns only <span>CocaCola.jpg</span>.

However, when I execute:

<span>Log("Exists CocaCola.jpg: " &amp; File.Exists(Main.PercorsoImmaginiPlu, "CocaCola.jpg"))<br>Log("Exists .jpg: " &amp; File.Exists(Main.PercorsoImmaginiPlu, ".jpg"))</span>
The output is:

<span>Exists CocaCola.jpg: true<br>Exists .jpg: true</span>
The second result is unexpected because there is no file named <span>.jpg</span> in the folder.

I also tested the full path:

<span>/storage/emulated/0/Pictures/RMenu/Images/Plu/.jpg</span>
<span>File.Exists</span> still returns <span>true</span>, even though <span>File.ListFiles</span> does not show a file with that name.

This causes my application to call <span>LoadBitmap</span> for <span>.jpg</span>, resulting in a <span>FileNotFoundException</span> and an <span>EACCES (Permission denied)</span> error.

Could this be a bug in <span>File.Exists</span>, or is there another explanation for this behavior on Android?

I would appreciate any suggestions on how to investigate this further.

Thank you.
 
This behavior is indeed surprising and confusing at first glance.
This type of issue generally stems from how the Android file system handles paths and file names, combined with the specific characteristics of the Android version running on your tablet.
Behind the scenes, `File.Exists` typically relies on the `java.io.File` object. When you pass a path to it, it checks for the existence of that item within the Android file system.

On certain file systems—or depending on how Android maps shared storage (`/storage/emulated/0/...`)—a string beginning with a dot (e.g., `.jpg`) can be interpreted ambiguously.
It is possible that the Java API misinterprets the concatenation of the folder path and the file name if the latter consists only of an extension, or that it performs a partial match or processes it as a wildcard.

If `Main.PercorsoImmaginiPlu` points to an external path, the virtual file system may occasionally return unexpected results if the file name does not follow a valid format (a file name should not consist solely of an extension).

Since `File.Exists` is no longer sufficient to guarantee that a valid file can be loaded (as it validates `.jpg`, which subsequently causes a crash during the read operation), the best practice is to validate the file name before calling `File.Exists`, or to strictly filter the extensions.

You could create a simple validation function, or, more straightforwardly, verify that the file name does not begin with a dot and contains a proper, non-empty name.

B4X:
If IsValidImageFileName(" .jpg ") Then
    ' Will not execute if the name is invalid
End If

Sub IsValidFileName(fileName As String) As Boolean
    ' Check whether the file is merely an extension or is empty.
    If fileName.Trim.Length = 0 Then Return False
    If fileName.StartsWith(".") Then Return False
    
    ' Optional: ensure that there are characters before the extension's dot
    Dim dotIndex As Int = fileName.LastIndexOf(".")
    If dotIndex <= 0 Then Return False ' No extension or starts with a dot
    
    Return True
End Sub

Even with checks in place, LoadBitmap can still fail (due to a corrupted file, permissions issues, etc.).
It is essential to wrap it in a Try / Catch block to prevent the application from crashing and to avoid the well-known EACCES / FileNotFoundException.
 
Upvote 0
Back
Top