File.Exists and File.Copy not working properly when the disk is full

Bruno Ferrari 0 Reputation points
2024-04-10T18:02:43.09+00:00

Hi!

First of all, code for reference:

if (!File.Exists(firstFile))
{
    File.Copy(secondFile, firstFile);
}

I'm having a problem while trying to copy a file using the File.Copy(string, string) method overload. It should throw an IOException('The file secondFile already exists') if the file already exists, but the file is overwritten instead.

The error occurs reportedly when the disk is full so I thought it was File.Exists() because the remarks in the documentation mentions "a failing or missing disk " may cause the method to return false.

But even if the 'if' statement evaluates to true when File.Copy() is executed it overwrites the file instead of throwing the exception. I tested it locally and File.Exists() works correctly and removing it causes File.Copy() to throw the exception.

I don't know if its useful information but both files are in different directories and have different names.

Thanks in advance!

Developer technologies | .NET | Other
Developer technologies | C#
{count} votes

1 answer

Sort by: Most helpful
  1. KOZ6.0 6,655 Reputation points
    2024-04-11T01:47:47.5166667+00:00

    How about asking for free space and then checking? For UNC, DriveInfo cannot be used, so GetDiskFreeSpaceEx API is used.

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
                                            out ulong lpFreeBytesAvailable,
                                            out ulong lpTotalNumberOfBytes,
                                            out ulong lpTotalNumberOfFreeBytes);
    
    private static bool IsDiskFull(string fileName) {
        string rootPath = Path.GetPathRoot(fileName);
        if (rootPath[rootPath.Length - 1] != Path.DirectorySeparatorChar) {
            rootPath += Path.DirectorySeparatorChar;
        }
        bool result = GetDiskFreeSpaceEx(rootPath,
                                         out var freeBytesAvailable,
                                         out var _,
                                         out var _);
        if (!result) {
            throw new Win32Exception();
        }
        return freeBytesAvailable == 0;
    }
    
    if (!IsDiskFull(firstFile) && !File.Exists(firstFile)) {
        File.Copy(secondFile, firstFile);
    }
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.