简体   繁体   中英

Title: C# File.Exist returning false when file can be read from/written to

Development Environment: .Net Framework 4.7.2 using VS 2022 on Win 10 Pro x64

Preface: I've reviewed the two similar questions I found at SO; the first deals with permissions and the second with restrictions on using the root directory. Neither contained info that enabled me to resolve my issue.

I'm working on a C# winforms app which uses a SQLite database. I recently discovered "PRAGMA integrity_check" will create an empty DB and return “ok” if the target DB file is missing so I need to ensure the file's not gone missing before executing the PRAGMA. My simple solution is to wrap integrity_check in an IF (File.Exist) ELSE but the Exist method is returning ”false”.

In MSDN documentation there 7 stated reasons why a false might be returned in addition to the file actually not existing (listed to avoid the need to follow a link):

  1. path is null

  2. path is invalid

  3. path exceeds maximum length (260)

  4. path is a zero-length string

  5. path has invalid characters

  6. storage media is failing/missing

  7. caller has insufficient permissions to read the specified file

My operating assumption is none of those are the root cause since I can read from and write to the DB programmatically in the app.

Code building the path:

namespace BURS_Library
{
    public class MISC
    {
        public const string DBName = "BURS.db";
    }
}

using System;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
namespace BURS_Library
{
    public class BURS_Path
    {
        public static string AppData()
        {
            string userAppDataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            userAppDataDir = userAppDataDir.Replace("Roaming", "LocalLow");
            if ( ! Directory.Exists(Path.Combine(userAppDataDir, "BURS_Data_tst")))
            {
                // display error MessageBox
                Environment.Exit(1);
            }
            return Path.Combine(userAppDataDir, "BURS_Data_tst");
        }
        public static string DB()
        {
            return Path.Combine(AppData(), MISC.DBName);
        }
    {
}

Resultant path: C:\Users\Art\AppData\LocalLow\BURS_Data_tst\BURS.db

Code with File.Exist

using _Library;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace BURS_UI
{
    public static class Program
    {
        [STAThread]
        public static void Main(string[] tsArgs)
        {
            if (File.Exists(BURS_Path.DB()))
            {
                // perform db Integrity Check
            }
            else
            {
                // display error MessageBox
                Environment.Exit(2);
            }
            BURS_Connections.SetConnection(BURS_Path.DB());

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Discover());
        }
    }
}

If my operating assumption is valid why is File.Exist returning false?

Thank you for your time & expertise.

Following @BentTranberg's suggestion a test was run using the following code (in case its useful to somebody):

if (Directory.Exists(@"C:\Users"))
    Save2Log(@"FOUND:  C:\Users", true);
if (Directory.Exists(@"C:\Users\Art"))
    Save2Log(@"FOUND:  C:\Users\Art", true);
if (Directory.Exists(@"C:\Users\Art\AppData"))
    Save2Log(@"FOUND:  C:\Users\Art\AppData", true);
if (Directory.Exists(@"C:\Users\Art\AppData\LocalLow"))
    Save2Log(@"FOUND:  C:\Users\Art\AppData\LocalLow", true);
if (Directory.Exists(@"C:\Users\Art\AppData\LocalLow\BURS_Data_tst"))
    Save2Log(@"FOUND:  C:\Users\Art\AppData\LocalLow\BURS_Data_tst", true);
if (File.Exists(@"C:\Users\Art\AppData\LocalLow\BURS_Data_tst\BURS.db"))
    Save2Log(@"FOUND:  C:\Users\Art\AppData\LocalLow\BURS_Data_tst\BURS.db", true);

Save2Log($"METHOD: {BURS_Path.DB()}", true);

Which produced the following result:

FOUND:  C:\Users
FOUND:  C:\Users\Art
FOUND:  C:\Users\Art\AppData
FOUND:  C:\Users\Art\AppData\LocalLow
FOUND:  C:\Users\Art\AppData\LocalLow\BURS_Data_tst
FOUND:  C:\Users\Art\AppData\LocalLow\BURS_Data_tst\BURS.db
METHOD: C:\Users\Art\AppData\LocalLow\BURS_Data_tst\BURS.db

Next I reran my original code which surprisingly now worked as expected. To validate that result I ran more test:

int existFail = 0;
for (int i = 0; i < 10000; i++)
{
    if ( ! File.Exists(BURS_Path.DB())) existFail++;
}

Save2Log($"number of exist fail in 10,000 = {existFail}", true);

I did that 5 times and in 50,000 iterations there were zero incorrect returns. At this point the error has not been reproduced.

My computer was shut down over night which may have impacted the findings. I will rerun this each morning for the next 3 days and post the results as an edit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM