JOCKH
JOCKH

Reputation: 407

How to force delete a file used by another process in Asp.net core

I'm working on an ASP.NET Core 5 project. I have this action method:

public async Task<IActionResult> CreateV3EnterCheckFile(IFormFile MarksFile)
{
    var filesCount = Directory.GetFiles("Uploads").Length;

    string path = Path.Combine("Uploads", filesCount + 1 + ".xlsx");

    await MarksFile.SaveToAsync(path);

    var xlImporter = new XLImporter();
    var importedData = await xlImporter.ImportSheetAsync(path, 0);

    var r = (from x in importedData select new { ID = x[0], StudentId = x[1] }).ToList();

    System.IO.File.Delete(path);

    return View();
}

I tried to get IFormFile uploaded file by the user to save it on the server and querying it using one of my projects (that uses LinqToExcel library).

I am querying the data and everything is perfect I still have just one problem it is this line of code:

System.IO.File.Delete(path);

It throws an exception and the message is I can't delete that file because it is still being used by another process.

I'm very sure that the process is related to the LinqToExcel library.

More details :

SaveToAsync is an extension method created by me that is its definition

 public static Task SaveToAsync(this IFormFile file, string pathToSaveTo)
        {
            return Task.Factory.StartNew(() =>
            {
                using (Stream fileStream = File.Open(pathToSaveTo, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
                {
                    file.CopyTo(fileStream);
                }
            });
        }

Please - is there any way or method or solution to delete this file even if it is being used by another process?

Massive thanks in advance.

Upvotes: 2

Views: 2284

Answers (2)

Pritom Sarkar
Pritom Sarkar

Reputation: 2252

I assumed that your Uploads folder is under webroot.

You can try this:-

 public YourControllerName(IHostingEnvironment he) //input parameter
        {
            
            _he = he;
        }

public async Task<IActionResult> CreateV3EnterCheckFile(IFormFile MarksFile)
{
try 
{ 
    var filesCount = Directory.GetFiles("Uploads").Length;
    
    string contentRootPath = _he.ContentRootPath;

    string path = Path.Combine(contentRootPath +"\\Uploads", filesCount + 1 + ".xlsx");
   

    await MarksFile.SaveToAsync(path);

    var xlImporter = new XLImporter();
    var importedData = await xlImporter.ImportSheetAsync(path, 0);

    var r = (from x in importedData select new { ID = x[0], StudentId = x[1] }).ToList();

    //System.IO.File.Delete(path);

   if (File.Exists(path))
    { 
        File.Delete(path);
    }
    else
    {
        Debug.WriteLine("File does not exist.");
    } 

    return View();
}  

 catch(Exception e) 
 { 
     Console.WriteLine(e); 
 }

Or you can try another process:-

try
{
 System.GC.Collect(); 
 System.GC.WaitForPendingFinalizers(); 
 System.IO.File.Delete(path);
}
catch(Exception e){
}
}

Or this:-

 if (System.IO.File.Exists(path))
        {
            try
            {
                System.GC.Collect();
                System.GC.WaitForPendingFinalizers();
                System.IO.File.Delete(path);

            }
            catch (Exception e) { }
        }

it should resolve your issue I hope. by the way, if your Upload folder is not under the webroot path. you can find your path using your process.

Upvotes: 1

Michael
Michael

Reputation: 1276

Based on the source code of ExcelQueryFactory (https://github.com/paulyoder/LinqToExcel/blob/master/src/LinqToExcel/ExcelQueryFactory.cs) I would try the following:

  • ExcelQueryFactory has a ReadOnly Property. For read only access (if applicable) I would set it to true when creating the instance.
  • More important: IExcelQueryFactory implements IDisposable, so you can (should) use a using block:
using (var excelFile = new ExcelQueryFactory(pathToExcelFile) {ReadOnly = true})
{
    // Do your work.
}

Of course you can use using var ..., but if you need a more reduced scope, the "old" using syntax allows more control.

Upvotes: 1

Related Questions