Как протестировать, если файл полностью копируется в.NET

Если Вы видите это предупреждение:

предупреждение: получатель 'MyCoolClass' является классом переадресации, и соответствующий @interface не может существовать

, Вам нужно к #import файл, но можно сделать это в файле реализации (.m) и использовать @class объявление в заголовочном файле.

@class (обычно) не устраняет необходимость к #import файлы, она просто спускает требование ближе туда, где информация полезна.

, Например

, Если Вы говорите @class MyCoolClass, компилятор знает, что может видеть что-то как:

MyCoolClass *myObject;

Это не должно волноваться ни о чем кроме MyCoolClass, допустимый класс, и это должно зарезервировать комнату для указателя на него (действительно, просто указатель). Таким образом, в Вашем заголовке, @class удовлетворяет 90% времени.

Однако, если когда-нибудь необходимо создавать или доступ myObject участники, необходимо будет сообщить компилятору, каковы те методы. В этой точке (по-видимому, в Вашем файле реализации), Вам будет нужно к #import "MyCoolClass.h", для сообщения дополнительной информации компилятора вне просто, "это - класс".

12
задан Viesturs 20 July 2009 в 07:47
поделиться

8 ответов

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

public bool FileIsDone(string path)
{
  try
  {
    using (File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
    {
    }
  }
  catch(UnauthorizedAccessException)
  {
    return false;
  }

  return true;
}
11
ответ дан 2 December 2019 в 21:04
поделиться

Не уверен насчет «правильного пути», но вы можете использовать инструмент мониторинга ( FileSystemWatcher , я думаю) для заполнения внутренней очереди, которую вы используете для отложенной обработки. Или еще лучше: просто используйте очередь для размещения файлов, открытие которых завершилось ошибкой, чтобы вы могли повторить их позже.

2
ответ дан 2 December 2019 в 21:04
поделиться

Если вы используете FileSystemWatcher , я не думаю, что есть надежное решение этой проблемы. Один из подходов - попробовать / поймать / повторить попытку позже.

1
ответ дан 2 December 2019 в 21:04
поделиться

Один из подходов, который я всегда использую, - это создать в конце моей копии / передачи файл с именем "token.txt" без содержимого. Идея заключается в том, что этот файл будет создан только в конце операции передачи, поэтому вы можете отслеживать создание этого файла, и когда этот файл создается, вы начинаете работать со своими файлами. Не забывайте всегда стирать этот файл токена, когда начинаете обрабатывать свои файлы.

0
ответ дан 2 December 2019 в 21:04
поделиться

Вы также должны учитывать такие случаи, как: файл используется другой программой, файл был удален (не удалось скопировать) и т. Д.

Используйте расширенную обработку исключений, чтобы охватить все важные случаи, которые могут произойти.

0
ответ дан 2 December 2019 в 21:04
поделиться

В зависимости от обстоятельств, цикл повтора, вероятно, лучшее, что вы можете сделать, если у вас нет контроля над процессом копирования.

Если у вас есть контроль:

  • Если папка локальная, вы можете потребовать, чтобы люди, которые пишут в нее, блокировали файл для монопольного доступа, и снимали блокировку только тогда, когда они закончили (что, я думаю, по умолчанию для File.Copy). На стороне .Net у вас может быть простой цикл повтора с периодом охлаждения.
    • В качестве альтернативы вы можете записать файл во временную папку и только после записи переместить его в целевой каталог. Это уменьшает окно, в котором могут происходить неприятные вещи (но не устраняет это)
  • Если папка является общим ресурсом SMB, есть вероятность, что LockFile даже не работает (некоторые реализации Linux). В этом случае общий подход состоит в том, чтобы иметь своего рода файл блокировки, который удаляется после того, как человек, создавший файл, закончит работу. Проблема с подходом к файлу блокировки заключается в том, что если вы забудете его удалить, у вас могут возникнуть проблемы.
  • Из-за этих осложнений я бы порекомендовал, чтобы получение данных через службу WCF или веб-службу могло быть выгодным, потому что у вас гораздо лучший контроль.
0
ответ дан 2 December 2019 в 21:04
поделиться

Фактически, чтобы избежать состояний гонки, единственное безопасное решение - повторить попытку.

Если вы сделаете что-то вроде:

while (file is locked)
    no-op()
process file()

Вы рискуете, что другой процесс перейдет между защитой while и выписка из файла процесса. Независимо от того, как реализовано ваше «ожидание доступности файла», если вы не можете гарантировать, что после разблокировки вы будете первым процессом, получившим к нему доступ, вы можете не быть этим первым пользователем.

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

0
ответ дан 2 December 2019 в 21:04
поделиться

Файлы большие?

Может быть, вы могли бы попытаться вычислить контрольную сумму md5 для файла?

Если вы поместите хэш md5 в имя файла, вы сможете получить его и попытаться пересчитать контрольную сумму файла. Когда md5 совпадает, можно предположить, что файл готов.

byte[] md5Hash = null;
MD5 md5 = new MD5CryptoServiceProvider();
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
   md5Hash = md5.ComputeHash(fs);

StringBuilder hex = new StringBuilder();
foreach (byte b in md5Hash)
    hex.Append(b.ToString("x2"));
0
ответ дан 2 December 2019 в 21:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: