-1

The error in the title appears when this code is executed:

using (var stream = new System.IO.FileStream(downloadPath + file.Id, System.IO.FileMode.Create))
{                               
    request.Download(stream);
}

specifically the line:

using (var stream = new System.IO.FileStream(downloadPath + file.Id, System.IO.FileMode.Create))

The purpose of this code is to download multiple spreadsheets and parse out the information to a database. This code executes normally for about 15 of the spreadsheets (there are about 100 - it differs with the day and what is input by remote users).

It accesses a shared google drive and loops through gathering the spreadsheets to parse out.

What would be causing it to create this error?

Here is the entire code:

public Dictionary<string,String[]> DownloadSpreadsheetsReturnLinks(string downloadPath, string[] sourceFolders = null, string[] spreadsheetNames = null)
    {
        try
        {
            if (!System.IO.Directory.Exists(downloadPath))
                System.IO.Directory.CreateDirectory(downloadPath);
            else
                System.IO.Directory.EnumerateFiles(downloadPath).ToList().ForEach(f => System.IO.File.Delete(f));

            Dictionary<string, string> folderList = null;
            if (sourceFolders != null)
            {
                var folders = GetFolderList();
                folderList = new Dictionary<string, string>();
                foreach (var folder in folders)
                {
                    if (sourceFolders.Contains(folder.Name))
                    {
                        folderList.Add(folder.Id, folder.Name);
                    }
                }
            }
            var fileLinks = new Dictionary<string, String[]>();
            var spreadsheets = GetFileList(Constants.SpreadsheetMimeType);
            foreach (var file in spreadsheets)
            {
                //dont download items in the trash
                if (file.Trashed.Value)
                    continue;
                //if we have folders then check the file is in one
                if (folderList == null || IsFileInFolder(file, folderList))
                {
                    if (spreadsheetNames == null || spreadsheetNames.Contains(file.Name))
                    {
                        //add our file to the dictionary
                        fileLinks.Add(file.Id, new string[] { file.Name, file.WebViewLink });
                        //var request = _driveService.Files.Export(file.Id, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                        var request = _driveService.Files.Export(file.Id, Constants.SpreadsheetMimeType2);
                        using (var stream = new System.IO.FileStream(downloadPath + file.Id, System.IO.FileMode.Create))
                        {                               
                            request.Download(stream);
                        }
                    }
                }
            }
            return fileLinks;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
Maximus
  • 1
  • 5
  • You're specifying `System.IO.FileMode.Create`. Is that intentional? Are you creating the file here or just downloading it? – Scott Hannen May 21 '19 at 17:29
  • Is it possible file.id is not unique? in that case, if two files hold the same id the exception would be logical when trying to create a file that's already been created previously – Avi Meltser May 21 '19 at 17:31
  • @ScottHannen I am creating the file in a new directory from a google drive – Maximus May 21 '19 at 17:32
  • Possible duplicate of [IOException: The process cannot access the file 'file path' because it is being used by another process](https://stackoverflow.com/questions/26741191/ioexception-the-process-cannot-access-the-file-file-path-because-it-is-being) – Trevor May 21 '19 at 17:33
  • @AviMeltser that was my initial thought as well but when I checked the stream all of the spreadsheets up to that point had unique id's. – Maximus May 21 '19 at 17:33
  • @Çöđěxěŕ nope I already looked over that one. Unless you are seeing something I am not – Maximus May 21 '19 at 17:34
  • Are any files created(with the content downloaded properly) before the exception is thrown? – Avi Meltser May 21 '19 at 17:36
  • @Maximus it's still a duplicate, [read](https://stackoverflow.com/a/26741192/1797425) that answer carefully... One way or another your accessing a file that is in use already *OR* another process is... The answers more than likely that will be here will mention the same details in that post in some form or fashion... – Trevor May 21 '19 at 17:36
  • @AviMeltser yes there were 15 other files created properly before the exception – Maximus May 21 '19 at 17:39
  • @Çöđěxěŕ ok maybe I did miss something I will take another look at it. – Maximus May 21 '19 at 17:40
  • My guess is that the files that threw the exception were previously downloaded as part of another request. If the file already exists and another request is in the process of downloading it this will throw an exception because one request will try to create the file while another has already created it and is writing it. Or if one process tries to read the file while another is writing it, same problem. – Scott Hannen May 21 '19 at 17:42
  • @Maximus it makes sense that up to that point they will have unique id's if "up to that point" means until the moment the exception was thrown. Would check again if file.id is a unique filed – Avi Meltser May 21 '19 at 17:45
  • Try changing the file name creation from `downloadPath + file.Id` to something that's 100% unique like `downloadPath + Guid.NewGuid()` and see if the problem persists – Avi Meltser May 21 '19 at 17:50
  • 1
    @AviMeltser That worked! It also showed me another error in another portion. Thank you for your help – Maximus May 21 '19 at 18:00

2 Answers2

0

As a quickfix, you can try putting a timer to create a delay after creating a file and downloading it.

 using (var stream = new System.IO.FileStream(downloadPath + file.Id, System.IO.FileMode.Create))
                    {               
                        Thread.Sleep(TimeSpan.FromSeconds(1));
                        request.Download(stream);
                    }

Or you can use the following to check if file is ready to be deleted.

Check if a file is in use, wait for it to finish

Gauravsa
  • 6,330
  • 2
  • 21
  • 30
  • How are you sure this is the problem, `As a quickfix you can try putting a timer...`, he could be creating files before any of this that has the files locked up... *and* why would you suggest putting a timer in? Also it's not a timer you are using, you are sleeping the UI thread, why? – Trevor May 21 '19 at 17:41
0

As Avi Meltser pointed out in the comments the solution is as follows:

Try changing the file name creation from downloadPath + file.Id to something that's 100% unique like downloadPath + Guid.NewGuid() and see if the problem persists

The problem was solved

Maximus
  • 1
  • 5