Должны ли мы проверять, существует ли файл для каждого из них при удалении нескольких файлов?

В приведенном ниже коде я проверяю, загружен ли файл, проверяя только одну папку, но я заметил, что код останавливается, если файл /new/name.ext не существует.

Нужно ли проверять каждый из них, чтобы продолжить работу с кодом? Есть ли способ продолжить работу с кодом, не проверяя, существует ли файл для каждого файла - или даже более простой способ?

   if (System.IO.File.Exists(HttpContext.Current.Server.MapPath("/products/cats/thumb/" + strGuid  + strExt))) {
       System.IO.File.Delete(HttpContext.Current.Server.MapPath("/products/cats/icons/" + strGuid  + strExt));
       System.IO.File.Delete(HttpContext.Current.Server.MapPath("/products/cats/thumb/" + strGuid  + strExt));
       System.IO.File.Delete(HttpContext.Current.Server.MapPath("/products/cats/new/" + strGuid + strExt));
       System.IO.File.Delete(HttpContext.Current.Server.MapPath("/products/cats/large/" + strGuid  + strExt));
       System.IO.File.Delete(HttpContext.Current.Server.MapPath("/products/cats/full/" + strGuid + strExt));
   }

3 ответа

Хотя я обычно не рекомендую "есть" исключения, это может быть исключением из этого правила.

Я бы написал один метод:

void DeleteFile(string filePath)
{
    try
    {
         if(File.Exists(filePath)
         {
             File.Delete(filePath);
         }
    }
    catch(DirectoryNotFoundException ex)
    {
         // depending on your environment you might
         // be prompted for some comment to indicate
         // that you meant to do this because
         // it's usually bad.
    }        
}

Только поймать DirectoryNotFoundException, Если каталог не существует, то файл не существует.

Причина размещения этого в отдельном методе заключается в том, что если вы обеспокоены этим сценарием, то вам не нужен Delete бросить исключение, которое удерживает последующие удаления от выполнения.

Мне не совсем удобно использовать обработку исключений для чего-либо, когда есть другой способ проверки. Лучше убедиться, что файл существует. Это только для крайней паранойи.

Вот вопрос - насколько вероятно удаление этих файлов и каталогов перед их удалением? И если один файл выдает исключение, которое не позволяет другим удалить, насколько серьезны последствия? Может быть, лучше просто позволить удалить ошибку, чем получить дополнительный параноид и перестать проверять обработку исключений. Но это короткий метод, поэтому, если вы беспокоитесь об этом, это не повредит. Но такого рода вещи могут стать привычкой.

Основываясь на рекомендациях Uwe Keim и источнике библиотеки ZetaLongPaths, он упомянул в своем комментарии (спасибо за это), и, поскольку мне не нужны все проблемы с длинным именем файла / путем, поэтому я выбрал несколько частей для обработки своего маленького приложения. Я не полностью протестировал его, но он прекрасно работает для кода в моем вопросе. Надеюсь, что кто-то может проверить и предоставить лучший проверенный код.

  using System;
  using System.ComponentModel;
  using System.Diagnostics;
  using System.IO;
  using System.Web.UI;
  using System.Web.UI.HtmlControls;


  //------------------------------------------------------------------------------
  // ZetaLongPaths/Source/Runtime/ZlpSafeFileOperations.cs 
  // https://github.com/UweKeim/ZetaLongPaths/blob/master/Source/Runtime/ZlpSafeFileOperations.cs#L30
  //------------------------------------------------------------------------------

  namespace MyNameSpace {

      public class FileHandling {


          //------------------------------------------------------------------------------
          ///<summary>
          /// Simple File Operations Handling 
          ///</summary>
          ///<remarks>
          /// 
          ///</remarks>
          //------------------------------------------------------------------------------


          public static bool SafeFileExists(FileInfo filePath) {
              return filePath != null && SafeFileExists(filePath.FullName);
          }

          public static bool SafeFileExists(string filePath) {
              return !string.IsNullOrEmpty(filePath) && System.IO.File.Exists(filePath);
          }
          public static void SafeMoveFile(FileInfo sourcePath, FileInfo dstFilePath) {
              SafeMoveFile(
                  sourcePath?.FullName.ToString(),
                  dstFilePath?.FullName);
          }
          public static void SafeDeleteFile(FileInfo filePath) {
              if (filePath != null) {
                  SafeDeleteFile(filePath.FullName);
              }
          }

          public static void SafeDeleteFile(
              string filePath) {
              Trace.TraceInformation(@"About to safe-delete file '{0}'.", filePath);

              if (!string.IsNullOrEmpty(filePath) && SafeFileExists(filePath)) {
                  try {
                      var attributes = System.IO.File.GetAttributes(filePath);

                      // Remove read-only attributes.
                      if ((attributes & FileAttributes.ReadOnly) != 0) {
                          System.IO.File.SetAttributes(
                              filePath,
                              attributes & (~(FileAttributes.ReadOnly)));
                      }

                      System.IO.File.Delete(filePath);
                  } catch (UnauthorizedAccessException x) {
                      var newFilePath =
                          $@"{filePath}.{Guid.NewGuid():N}.deleted";

                      Trace.TraceWarning(@"Caught UnauthorizedAccessException while deleting file '{0}'. " +
                                         @"Renaming now to '{1}'. {2}", filePath, newFilePath, x.Message);

                      try {
                          System.IO.File.Move(
                              filePath,
                              newFilePath);
                      } catch (Win32Exception x2) {
                          Trace.TraceWarning(@"Caught IOException while renaming upon failed deleting file '{0}'. " +
                                             @"Renaming now to '{1}'. {2}", filePath, newFilePath, x2.Message);
                      }
                  } catch (Win32Exception x) {
                      var newFilePath =
                          $@"{filePath}.{Guid.NewGuid():N}.deleted";

                      Trace.TraceWarning(@"Caught IOException while deleting file '{0}'. " +
                                         @"Renaming now to '{1}'. {2}", filePath, newFilePath, x.Message);

                      try {
                          System.IO.File.Move(
                              filePath,
                              newFilePath);
                      } catch (Win32Exception x2) {
                          Trace.TraceWarning(@"Caught IOException while renaming upon failed deleting file '{0}'. " +
                                             @"Renaming now to '{1}'. {2}", filePath, newFilePath, x2.Message);
                      }
                  }
              } else {
                  Trace.TraceInformation(@"Not safe-deleting file '{0}', " +
                                         @"because the file does not exist.", filePath);
              }
          }
          public static void SafeMoveFile(string sourcePath, string dstFilePath) {
              Trace.TraceInformation(@"About to safe-move file from '{0}' to '{1}'.", sourcePath, dstFilePath);

              if (sourcePath == null || dstFilePath == null) {
                  Trace.TraceInformation(
                      string.Format(
                          @"Source file path or destination file path does not exist. " +
                          @"Not moving."
                          ));
              } else {
                  if (SafeFileExists(sourcePath)) {
                      SafeDeleteFile(dstFilePath);

                      var d = Path.GetDirectoryName(dstFilePath);

                      if (!System.IO.Directory.Exists(d)) {
                          Trace.TraceInformation(@"Creating non-existing folder '{0}'.", d);
                          System.IO.Directory.CreateDirectory(d);
                      }

                      System.IO.File.Move(sourcePath, dstFilePath);
                  } else {
                      Trace.TraceInformation(@"Source file path to move does not exist: '{0}'.", sourcePath);
                  }
              }
          }

      }
  }

Затем проверено с

   if (MyNameSpace.FileHandling.SafeFileExists(HttpContext.Current.Server.MapPath("/products/cats/thumb/" + strGuid  + strExt))) {

      MyNameSpace.FileHandling.SafeDeleteFile(HttpContext.Current.Server.MapPath("/products/cats/icons/" + strGuid  + strExt).ToString());
      MyNameSpace.FileHandling.SafeDeleteFile(HttpContext.Current.Server.MapPath("/products/cats/thumb/" + strGuid  + strExt).ToString());
      MyNameSpace.FileHandling.SafeDeleteFile(HttpContext.Current.Server.MapPath("/products/cats/new/" + strGuid + strExt).ToString());
      MyNameSpace.FileHandling.SafeDeleteFile(HttpContext.Current.Server.MapPath("/products/cats/large/" + strGuid  + strExt).ToString());
      MyNameSpace.FileHandling.SafeDeleteFile(HttpContext.Current.Server.MapPath("/products/cats/full/" + strGuid + strExt).ToString());

   }

Не могли бы вы просто перебрать все файлы в папке..cats/ и ее подпапках с правильными атрибутами (имя / расширение)? Тогда вы можете просто использовать System.IO.File.Exists().

if (System.IO.File.Exists(Path/to/file.ext)){
    System.IO.File.Delete(Path/to/file.ext);
}

Итерация может быть выполнена, находя все файлы с

string[] files = Directory.GetFiles(txtFolderPath.Text, "*ProfileHandler.cs", SearchOption.AllDirectories);

а затем просто делать что-то вроде:

foreach(file in files){
if (System.IO.File.Exists(Path/to/file.ext)){
        System.IO.File.Delete(Path/to/file.ext);
    }

}

E: Извините за невозможность дать вам точный синтаксис, в настоящее время используется компьютер без надлежащей IDE для написания и тестирования кода.

Другие вопросы по тегам