Why do I sometimes get System.IO.IOException: The file '/sdcard' already exists on Xamarin.Android?

169 Views Asked by At

In our production app we rarely get this exception which causes our app to crash: System.IO.IOException: The file '/sdcard' already exists

The app is a Xamarin.Forms app written in C# and runs on thousands of our own devices with Android 8.1 and 10. At every app start in the constructor of the App class we create a connection to an SQLite database. The database file is stored on the external storage under /sdcard/mycompany/somesubfolder. The devices don't use real SD-cards as storage though but the built-in storage.

Here is the method where the exception is thrown.

protected SQLiteAsyncConnection CreateDatabaseConnection(string databaseFilePath)
{
    if (string.IsNullOrWhiteSpace(databaseFilePath))
        throw new ArgumentOutOfRangeException(nameof(databaseFilePath), "Argument cannot be null, empty or whitespace!");

    var directory = Path.GetDirectoryName(databaseFilePath);

    try
    {
        if (directory != null && !Directory.Exists(directory))
            Directory.CreateDirectory(directory);
    }
    catch (Exception ex)
    {
        var metaData = new Dictionary<string, string>
        {
            { "DatabaseFilePath", databaseFilePath },
            { "Directory", directory }
        };

        LoggingService.ReportException(ex, metaData);

        throw;
    }

    return CreateAsyncDbConnection(databaseFilePath);
}

In case of the exception both databaseFilePath and directory have proper values and are not null.

The databaseFilePath is created with Path.Combine() and consists of the following parts:

  • storage path: sdcard (determined with Environment.ExternalStorageDirectory.AbsolutePath)
  • bundle identifier: com.mycompany.myapp (determined with ApplicationInfo.PackageName)
  • database folder: database (hardcoded string)
  • database file name: mydatabasefile.db3 (hardcoded string)

and looks like this: /sdcard/com.mycompany.myapp/database/mydatabasefile.db3

The directory is the same but without the database file name: /sdcard/com.mycompany.myapp/database

The exception does not occur a second time when the app is started again on the same device.

We also track our crashes with AppCenter. This is the reported stack trace:

FileSystem.CreateDirectory (System.String fullPath)
Directory.CreateDirectory (System.String path)
DatabaseConnectionProviderBase.CreateDatabaseConnection (System.String databaseFilePath)
0

There are 0 best solutions below