简体   繁体   中英

C# - File.Move - Could not find file

i have a strange problem with File.Move method. Generally I have a service, that monitors for new files appearing on remote share and once they do it changes its extension via "ren" cmd function and calls other service. This other service is then using File.Move to change the extension of the file once again. The problem is that from time to time the second service fails and returns error "Could not find file..." from System.IO.File.InternalMove, while the file is already there.

Initially I thought that it may be issue with network connection, but I have a feeling that it happens to often to be caused by network problems.

Next I started digging into .net source code and found something interesting:

        if (!InternalExists(fullSourceFileName))
             __Error.WinIOError(Win32Native.ERROR_FILE_NOT_FOUND, fullSourceFileName);
        
        if (!Win32Native.MoveFile(fullSourceFileName, fullDestFileName))
        {
            __Error.WinIOError();
        }

This is part of File.InternalMove method which, from my understanding, is returning an "Could not find file..." error. In short InternalExists method is checking if file exists by checking the Marshal.GetLastWin32Error() error and later verifing attributes on file.

Also what is strange is that it seems that this method is using "hack" of some sort (don't know if it is related to my problem, but it is worrying):

   // For floppy drives, normally the OS will pop up a dialog saying
            // there is no disk in drive A:, please insert one.  We don't want that.
            // SetErrorMode will let us disable this, but we should set the error
            // mode back, since this may have wide-ranging effects.
            bool success = false;
            int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
            try {
                success = Win32Native.GetFileAttributesEx(path, GetFileExInfoStandard, ref data);
            }
            finally {
                Win32Native.SetErrorMode(oldMode);
            }

Now the interestring part:) Class FileInfo also allows to rename files via MoveTo() method. In this method the "moving" part is following:

 if (!Win32Native.MoveFile(FullPath, fullDestFileName))
            __Error.WinIOError();

It is the same as in File class, but it lacks the "InternalExists" verification, so at a glance it looks like it should resolve my problem, but I am little worried about this missing check.

Does anybody knows why it is implemented like this and if I can use FileInfo.MoveTo method? Also if you have any ideas on the cause of the problem, then please share it. Currently I am quessing that when first service is calling "ren" cmd program, the new file isn't fully renamed yet, which causes File.Move method to fail, but I have to yet verify it.

I'm guessing the error is actually a permissions issue, or possibly a locked file, and that the error returned by InternalExists isn't actually ERROR_FILE_NOT_FOUND , as no check is made on it.

Therefore it's a bug that the correct error is not thrown.

Why the Exists check needs to be there is unclear anyway: if it's not there you will get an error anyway when calling MoveFile .

I suggest you file this as a bug on the GitHub repo. I think it's unlikely to get fixed, but at least it will be documented. If it gets closed as Won't fix you may want to file a pull request on the documentation noting this.

Note that the current code is actually the following, which implements the same thing in a slightly different way.

            if (!FileSystem.FileExists(fullSourceFileName))
            {
                throw new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, fullSourceFileName), fullSourceFileName);
            }

            FileSystem.MoveFile(fullSourceFileName, fullDestFileName, overwrite);

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