Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.IO.File.Move error - Could not find a part of the path

Tags:

c#

file-move

I have a sync software, which loads CSV files from "Incoming" folder, processes them and then moves them to the "Archive" folder.

Today, I saw the following error with this sync software:

[23/06/2014 00:06:04 AM] : Failed to move file from

D:\IBI_ORDER_IMPORTER_FTP_SERVER\Template3\Fifty & Dean\Incoming\5A040K___d6f1ca45937b4ceb98d29d0db4601bf4.csv to

D:\IBI_ORDER_IMPORTER_FTP_SERVER\Template3\Fifty & Dean\Archive\5A040K___d6f1ca45937b4ceb98d29d0db4601bf4.csv - Could not find a part of the path.

Here's a snippet taken out of the sync software, where the file is processed and moved:

public static void ProcessSingleUserFile(Int32 TemplateId, String ImportedBy, String FilePath)
{
    // Always Rename File To Avoid Conflict
    string FileName = Path.GetFileNameWithoutExtension(FilePath);
    String NewFilePath = FilePath.Replace(FileName, Utils.RandomString() + "___" + FileName);
    File.Move(FilePath, NewFilePath);
    FilePath = NewFilePath;

    // Log
    SyncUtils.ConsoleLog(String.Format("Processing [ {0} as {1} ] By [ {2} ] On Template [ #{3} ]",
        FileName + ".csv",
        Path.GetFileName(FilePath),
        ImportedBy,
        TemplateId));

    // Init
    List<OrderDraft> myOrderDrafts = new List<OrderDraft>();

    // Parsed Based On Template Id
    if (TemplateId == Settings.Default.Multi_Order_Template_Id)
    {
        // Try Parse File
        myOrderDrafts = Utils.ParseMultiImportFile(TemplateId, ImportedBy, FilePath, true);
    }
    else
    {
        // Try Parse File
        myOrderDrafts.Add(Utils.ParseImportFile(TemplateId, ImportedBy, FilePath, true));
    }

    // Process Orders
    foreach (OrderDraft myOrderDraft in myOrderDrafts)
    {
        /* code snipped */
    }

    // Archive File
    File.Move(FilePath, FilePath.Replace("Incoming", "Archive"));
}

Any idea what this error means? and how to circumvent it?


I wrote a cut down version of the above to test this in a controlled environment and I am not getting the error with this code:

static void Main(string[] args)
{
    try
    {
        string baseDir = @"C:\Users\Administrator\Desktop\FTP_SERVER\Template3\Fifty & Dean\Incoming\";

        string[] filePaths = Directory.GetFiles(baseDir, "*.csv");

        foreach (string filePath in filePaths)
        {
            // do some work here ...

            // move file
            string newFilePath = filePath.Replace("Incoming", "Archive");
            File.Move(filePath, newFilePath);
            Console.WriteLine("File successfully moved");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error: " + ex.Message);
    }

    Console.ReadKey();
}
like image 308
Latheesan Avatar asked Jun 25 '14 13:06

Latheesan


2 Answers

You need to include the checks to make sure that the paths exist at runtime and check the output, something very simple like:

if(!Directory.Exists(Path.GetDirectoryName(filePath)))
{
   Console.WriteLine("filePath does not exist: " + filePath);
}

if(!Directory.Exists(Path.GetDirectoryName(newFilePath)))
{
   Console.WriteLine("newFilePath does not exist: " + newFilePath);
}
File.Move(filePath, newFilePath);

The reason I am suggesting this method is due to a possibility that the paths momentarily become available or not under the multi-tasking OSs depending on a multitude of factors: network connectivity, permissions (pushed down by GPO at any time), firewall rules, AV exclusions getting blown away etc. Even running low on CPU or RAM may create issues. In short, you never know what exactly occurred when your code was running if you are only checking the paths availability after the fact.

Or if your issue is intermittent, you can try and catch the error and write information to some sort of a log similarly to below:

try
{
    File.Move(filePath, newFilePath);
}
catch(Exception ex)
{
    if(!Directory.Exists(Path.GetDirectoryName(filePath)))
    {
       Console.WriteLine("filePath does not exist: " + filePath);
    }

    if(!Directory.Exists(Path.GetDirectoryName(newFilePath)))
    {
       Console.WriteLine("newFilePath does not exist: " + newFilePath);
    }
}
like image 75
ajeh Avatar answered Oct 09 '22 17:10

ajeh


"Could not find a part of the path" exception could also thrown from File.Move if argument used was longer than MAX_PATH (260) in .NET Framework.

So I prepend the path I used with long path syntax before passing to File.Move and it worked.

// Prepend long file path support
if( !packageFile.StartsWith( @"\\?\" ) )
    packageFile = @"\\?\" + packageFile;

See: How to deal with files with a name longer than 259 characters?

like image 1
Wappenull Avatar answered Oct 09 '22 18:10

Wappenull