Можно ли обойти блокировку файлов в С#, когда другой поток/процесс имеет необходимость использовать исключительную блокировку?

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

Я использую стороннюю библиотеку в своем приложении, которая выполняет операции только для чтения в файле. Мне нужно, чтобы второй поток читал файл в то же время, чтобы извлечь лишние данные, которые сторонняя библиотека не раскрывает. К сожалению, сторонняя библиотека открыла файл, используя блокировку чтения/записи, и, следовательно, я получаю обычный "Процесс не может получить доступ к файлу... потому что он используется другим процессом".

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

Я не могу изменить стороннюю библиотеку.

Есть ли проблемы в этой проблеме?

Ответ 1

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

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

Ответ 2

Короче говоря, вы ничего не можете сделать о блокировке файла сторонним. Вы можете уйти с ответом Ричарда E выше, в котором упоминается утилита Unlocker.

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

  • Использование DLL-инъекции для исправления кода, чтобы явно установить блокировку или отключить ее. Это может быть опасно, поскольку вы будете возиться с другой стабильностью процесса и, возможно, в конечном итоге разрушите процесс и проявите горе. Подумайте об этом, базовая система отслеживает файлы, открытые процессом. DLL-инъекция в точке и исправление кода - для этого требуются технические знания, чтобы определить, какой процесс вы хотите внедрить во время выполнения и изменить флаги при перехвате вызова API Win32 OpenFile(...).
  • Поскольку это было помечено как .NET, почему бы не разобрать источник сторонних файлов в .il и изменить флаг блокировки для совместного использования, перестроить библиотеку, перекомпилировав все файлы .il обратно в DLL, Это, конечно же, потребует корень вокруг кода, где открытие файла происходит где-то в каком-то классе.

Посмотрите на подкаст здесь. И посмотрите здесь, где объясняется, как сделать второй вариант, выделенный выше, здесь.

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

Ответ 3

Это не касается вашей ситуации напрямую, но такой инструмент, как Unlocker, делает то, что вы пытаетесь сделать, но через пользовательский интерфейс Windows.

Ответ 4

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

Следовательно, я думал, что буду упомянуть следующее самое лучшее, просто подождите свою очередь и опрос, пока файл не заблокирован: fooobar.com/questions/12888/...


Я не думаю, что этот второй совет поможет, но самое близкое (что я знаю) будет DemandReadFileIO:
IntSecurity.DemandReadFileIO(filename);

internal static void DemandReadFileIO(string fileName) 
{
   string full = fileName;            
   full = UnsafeGetFullPath(fileName); 
   new FileIOPermission(FileIOPermissionAccess.Read, full).Demand();
}

Ответ 5

Я действительно думаю, что это проблема, которая может быть решена с помощью С++. Это раздражает, но, по крайней мере, это работает (как описано здесь: win32 C/С++ читает данные из файла "заблокирован" )

Шаги:

  • Откройте файл перед третьей библиотекой с помощью fsopen и флага _SH_DENYNO
  • Откройте файл с третьей библиотекой
  • Прочитайте файл в своем коде

Вам могут быть интересны и эти ссылки:

Ответ 6

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

Ответ 7

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