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!

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,851 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,924 questions
{count} votes

1 answer

Sort by: Most helpful
  1. KOZ6.0 6,400 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.