istudent Ответов: 1

Ошибка: процесс не может получить доступ к файлу, поскольку он используется другим процессом.


I have created a file watcher processor which transforms xls file to csv file once the file gets dropped in the folder.

While doing so i get the error The process cannot access the file '\\somepath\someotherpath\user\FileName_2018.xls' because it is being used by another process.


Что я уже пробовал:

private static string sourcePath = ConfigurationManager.AppSettings["Excel"];
       private static string destination = ConfigurationManager.AppSettings["CSV"];
       private static string xlsFileName = string.Empty;
       static void Main(string[] args)
       {
           FileSystemWatcher watcher = new FileSystemWatcher
           {
               Filter = "*.xls",
               Path = sourcePath,
               EnableRaisingEvents = true
           };
           watcher.Created += new FileSystemEventHandler(Watcher_Created);
           Console.WriteLine($"FileSystemWatcher ready and listening to changes in :\n\n{sourcePath}");
           Console.Read();
       }
       static void Watcher_Created(object sender, FileSystemEventArgs e)
       {
           xlsFileName = e.Name;

           var filePath = sourcePath + xlsFileName;
           var extension = Path.GetExtension(filePath);

           if (extension.ToLower() == ".xls")
           {
               Console.WriteLine($"\n{xlsFileName} file is saved and ready to be processed.");
               PerformETL(xlsFileName);
           }
       }

       private static void PerformETL(string xlsFile)
       {
           try
           {
               var isCSVFileCreated = false;
               var filePath = sourcePath + xlsFile;
               var extension = Path.GetExtension(filePath);
               var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(xlsFile);

               if (extension.ToLower() == ".xls")
               {
                   IExcelDataReader excelReader;
                   DataSet dataset;

                   using (FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
                   {
                       excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
                       dataset = excelReader.AsDataSet();
                   }

                   DataTable dtTemplate = dataset.Tables[0];

                   using (var output = File.CreateText($"{destination}{fileNameWithoutExtension}.csv"))
                   {
                       for (int i = 5; i < dtTemplate.Rows.Count; i++)
                       {
                           // 7 spaces
                           output.WriteLine($"{dtTemplate.Rows[i][3].ToString().Trim()},{dtTemplate.Rows[i][4].ToString().Trim().PadLeft(9, '0')}");
                       }
                   }

                   isCSVFileCreated = true;
               }
               else
               {
                   isCSVFileCreated = false;
               }

               if (isCSVFileCreated)
               {
                   Console.WriteLine("File is extracted and transformed to space delimited file format");
               }
               else
               {
                   Console.WriteLine("File is extracted and transformed to space delimited file format");
               }

               DeleteExcelFile(filePath);
           }
           catch (Exception ex)
           {
               Console.WriteLine($"error: {ex.Message}");
           }
       }

       private static void DeleteExcelFile(string filePath)
       {
           var fileName = Path.GetFileName(filePath);
           if (File.Exists(filePath))
           {
               File.Delete(filePath);
           }
           Console.WriteLine($"{fileName} is deleted.");
       }

1 Ответов

Рейтинг:
1

Dave Kreskowiak

Проблема, которую я сразу вижу у людей, использующих FileSystemWatcher, заключается в том, что люди предполагают, что "созданное" событие срабатывает при записи файла.

Ошибаешься! Как и сказано в событии, файл создан. Это никоим образом не означает, что файл будет записан другим приложением. Если вы попытаетесь открыть файл, пока Excel все еще пишет его, вы получите исключение, которое вы описываете.

Они обходят это, чтобы создать цикл для повторной попытки открытия файла через короткий промежуток времени и продолжать повторять его до тех пор, пока файл наконец не откроется, или вы не достигнете заданного количества повторений в своем цикле.


istudent

не могли бы вы поделиться кодом, как мне это сделать? спасибо

Dave Kreskowiak

Это простой цикл со счетчиком количества повторных попыток. Что в этом такого сложного?

istudent

спасибо.