System io ioexception процесс не может получить доступ к файлу
Одновременно работать с конкретным файлом может только одна программа. Речь идет не о библиотеках общего использования, которые используются только для извлечения данных, а об элементах, предназначенных для перезаписи. Если это кэш-файл игры, здесь содержится пользовательская информация или происходит постоянная обработка данных, и Windows накладывает ограничение. Данные файлы становятся недоступными для удаления или ручного изменения до тех пор, пока мы не завершим процесс, использующий их.
Как удалить файл, если процесс не может получить доступ к файлу?
Следуя по логической цепочке, для удаления любого файла, нужно сначала выгрузить его с оперативной памяти и со всех программ. Как только он перестанет использоваться системой в каких-то процессах, элемент сразу станет доступным для удаления.
Главная сложность данного вопроса в том, чтобы найти процесс, использующий конкретный файл. Это не всегда очевидно. Часто бывает, что изображение использует какая-то игра, браузер, торрент, медиапроигрыватель. Если в первую очередь подумать на программу просмотра картинок, вы ошибетесь. Нужно смотреть куда глубже.
Как можно решить проблему «процесс не может получить доступ к файлу»:
- Unlocker – специальная программа, созданная как раз для подобных ситуаций. Она автоматически обнаруживает связанные с файлом процессы и завершает их. По сути она делает то же самое, что нужно выполнять вручную, но только в автоматическом режиме. Она имеет минимальный размер и проверена во многих системах, поэтому точно не заражена вирусами. После скачивания и установки, нужно нажать правой кнопкой мыши по файлу и выбрать «Unlock».
- Завершить связанные процессы. Обычно вполне реально догадаться, какая именно задача использует файл. Для этого нужно открыть Ctrl + Shift + Esc и развернуть список «Подробнее». Здесь будет довольно много процессов, но большинство из них системные, нужно найти те, которые были запущены пользователем. Чтобы удалить файл кэша Google Chrome, нужно закрыть все задачи Google. Для их завершения нужно нажать правой кнопкой мыши и выбрать «Снять задачу».
- Установить правильные атрибуты. К каждому файлу можно установить подходящие привилегии. Нужно нажать правой кнопкой мыши по файлу и на вкладке «Общие» установить пункт «Только чтение». После перезагрузки компьютера возможность удаления может появиться.
- Удаление в безопасном режиме. Очень часто это срабатывает, так как при данном способе запуска система не загружает все посторонние программы. Нужно кликнуть на перезапуск ПК и в момент пуска нажать клавишу F8 (может быть другая) для выбора варианта запуска. В безопасном режиме удалить можно практически любой файл.
- Снять защиту диска на запись. Она может быть установлена на программном и физическом уровне. Первым делом нужно посмотреть на накопителе (обычно это флешка), нет ли здесь специального тумблера. Рядом должна быть соответствующая пометка. В системе в редакторе реестра также следует найти параметр WriteProtect и установить ему значение 0.
Точно такая же самая ошибка «процесс не может получить доступ к файлу» может появиться при запуске команды netsh или при выполнении настройки сайта IIS. В таком случае проблема может быть вызвана недостатком прав для выполнения действия, попытке подключения к занятым портам 80 и 443 или некорректной настройкой реестра.
Сопоставление кодов ошибок с исключениями
Например, при вызове метода в операционной системе Windows код ошибки ERROR_FILE_NOT_FOUND (или 0x02) преобразуется в исключение FileNotFoundException, а код ошибки ERROR_PATH_NOT_FOUND (или 0x03) — в DirectoryNotFoundException.
К сожалению, точные условия возникновения определенных кодов ошибок в операционной системе часто не документируются или документируются в недостаточном объеме. Это означает, что возможны непредвиденные исключения. Например, при работе с каталогом логично ожидать, что передача недопустимого пути в конструктор DirectoryInfo приведет к созданию исключения DirectoryNotFoundException. Но в этой ситуации может создаваться и FileNotFoundException.
Обработка исключений при операциях ввода-вывода
По причине зависимости от операционной системы иногда идентичные условия (например, отсутствие указанного каталога) могут создавать в методах ввода-вывода любое исключение из класса ввода-вывода. Это означает, что при вызове интерфейсов API ввода-вывода ваш код должн быть готов обработать все такие исключения или большую их часть, как показано в следующей таблице:
Обработка IOException
IOException является базовым классом для исключений в пространстве имен System.IO и создается для любого кода ошибки, который не имеет сопоставления с определенным типом исключения. Это означает, что оно может появиться в любой операции ввода-вывода.
Так как IOException является базовым классом для других типов исключений в пространстве имен System.IO, его нужно обрабатывать в блоке catch после обработки других исключений, связанных с вводом-выводом.
Обратите внимание, что в коде обработки исключений IOException всегда нужно обрабатывать последним. Иначе блоки catch для производных классов не проверяются, ведь это исключение является базовым классом для всех остальных.
В случае с IOException дополнительные сведения об ошибке можно получить из свойства IOException.HResult. Чтобы преобразовать значение HResult в код ошибки Win32, отбросьте верхние 16 бит из 32-разрядного значения. В приведенной ниже таблице перечислены коды ошибок, которые могут быть заключены в IOException.
HResult | Константа | Описание |
---|---|---|
ERROR_SHARING_VIOLATION | 32 | Отсутствует имя файла, или файл или каталог уже используется. |
ERROR_FILE_EXISTS | 80 | Файл уже существует. |
ERROR_INVALID_PARAMETER | 87 | Методу передан недопустимый аргумент. |
ERROR_ALREADY_EXISTS | 183 | Файл или каталог уже существует. |
Для обработки этих исключений можно применить предложение When в инструкции catch, как показано в приведенном ниже примере.
Отладка
Это может быть довольно легко решить (или довольно трудно понять), в зависимости от вашего конкретного сценария. Посмотрим на некоторые.
К счастью, FileStream реализует IDisposable , поэтому легко обернуть весь ваш код внутри инструкции using :
Этот шаблон также гарантирует, что файл не останется открытым в случае исключений (может быть, причина в том, что файл используется: что-то пошло не так, и никто его не закрыл, см. этот пост для примера).
Обратите внимание на общую ошибку, которую мы часто видим в StackOverflow:
В этом случае ReadAllText() будет терпеть неудачу, потому что файл используется ( File.Open() в строке перед). Чтобы открыть файл заранее, это не только лишний, но и неправильный. То же самое относится ко всем функциям File , которые не возвращают дескриптор файла, с которым вы работаете: File.ReadAllText() , File.WriteAllText() , File.ReadAllLines() , File.WriteAllLines() и другие (например, функции File.AppendAllXyz() ) будут все открывают и закрывают файл самостоятельно.
Ваш процесс не является единственным для доступа к этому файлу
Если ваш процесс не является единственным для доступа к этому файлу, то взаимодействие может быть сложнее. Шаблон повторения поможет (если файл не должен открываться кем-либо другим, но он есть, то вам нужна утилита, например Process Explorer, чтобы проверить, кто что делает).
Способы избежать
Когда это применимо, всегда используйте с помощью операторов для открытия файлов. Как сказано в предыдущем абзаце, он будет активно помогать вам избежать многих распространенных ошибок (см. этот пост для примера на , как не использовать его).
Если возможно, попробуйте решить, кому принадлежит доступ к определенному файлу, и централизовать доступ с помощью нескольких известных методов. Если, например, у вас есть файл данных, в котором ваша программа читает и записывает, тогда вы должны вставить весь код ввода/вывода внутри одного класса. Это облегчит отладку (потому что вы всегда можете поставить точку останова и посмотреть, кто что делает), а также будет точкой синхронизации (если требуется) для множественного доступа.
Не забывайте, что операции ввода-вывода всегда могут быть провалены, например:
Если кто-то удалит файл после File.Exists() , но до File.Delete() , то он выкинет IOException в том месте, где вы можете ошибочно чувствовать себя в безопасности.
Когда это возможно, примените шаблон повтора, и если вы используете FileSystemWatcher , подумайте о переносе действия (потому что вы получите уведомление, но приложение все еще может работать исключительно с этим файлом).
Расширенные сценарии
Это не всегда так просто, поэтому вам может потребоваться предоставить доступ к кому-то другому. Если, например, вы читаете с самого начала и записываете до конца, у вас есть как минимум два варианта.
1) используют один и тот же FileStream с надлежащими функциями синхронизации (поскольку он не является потокобезопасным). См. this и для примера.
2) используйте перечисление FileShare , чтобы указать ОС, чтобы другие процессы (или другие части вашего собственного процесса) могли одновременно обращаться к одному и тому же файлу.
В этом примере я показал, как открыть файл для записи и поделиться для чтения; обратите внимание, что при чтении и записи перекрывается, это приводит к undefined или неверным данным. Это ситуация, которая должна решаться при чтении. Также обратите внимание, что это не делает доступ к потоку stream потокобезопасным, поэтому этот объект нельзя обменивать несколькими потоками, если доступ не синхронизирован каким-либо образом (см. Предыдущие ссылки). Доступны другие варианты совместного доступа, и они открывают более сложные сценарии. Подробнее см. MSDN.
В общем случае процессы N могут считывать из одного и того же файла все вместе, но только один должен писать, в контролируемом сценарии вы можете даже разрешать одновременные записи, но это не может быть обобщено в нескольких текстовых абзацах внутри этого ответа.
Можно ли разблокировать файл, используемый другим процессом? Это не всегда безопасно и не так просто, но да, это возможно.
Использование FileShare исправило мою проблему открытия файла, даже если он открывается другим процессом.
Возникла проблема при загрузке изображения и не удалось удалить его и найти решение. gl hf
Я получил эту ошибку, потому что я делал File.Move до пути к файлу без имени файла, вам нужно указать полный путь в пункте назначения.
У меня был следующий сценарий, который вызывал ту же ошибку:
- Загрузка файлов на сервер
- Затем избавиться от старых файлов после их загрузки
Большинство файлов были маленькими по размеру, однако некоторые из них были большими, поэтому попытка удалить те, которые привели к невозможности доступа к ошибке файла.
Как указывалось в других ответах в этом потоке, для устранения этой ошибки вам необходимо тщательно проверить код, чтобы понять, где файл заблокирован.
В моем случае я отправлял файл в виде вложения электронной почты перед выполнением операции перемещения.
Таким образом, файл был заблокирован на пару секунд, пока клиент SMTP не завершил отправку электронной почты.
Другое возможное решение, как было указано ранее Хадсоном, было бы уничтожить объект после использования.
Есть некоторые основные вещи, чтобы избежать этого, как упомянули другие ответы:
- В операциях FileStream поместите его в using блок с помощью режима доступа FileShare.ReadWrite .
Обратите внимание, что FileAccess.ReadWrite невозможен, если вы используете FileMode.Append .
Я столкнулся с этой проблемой, когда я использовал входной поток для File.SaveAs файла File.SaveAs когда файл использовался. В моем случае я обнаружил, что мне фактически не нужно было сохранять его обратно в файловую систему вообще, поэтому я просто удалил это, но я, возможно, попытался создать FileStream в операторе using с FileAccess.ReadWrite , как код выше.
Сохранение ваших данных в виде другого файла и возврат к удалению старого, когда оно больше не используется, переименование того, которое было успешно сохранено на имя исходного, является опцией. Как вы проверяете используемый файл, выполняется через List<Process> lstProcs = ProcessHandler.WhoIsLocking(file); строка в моем коде ниже и может быть выполнена в службе Windows в цикле, если у вас есть определенный файл, который вы хотите регулярно смотреть и удалять, когда хотите его заменить. Если у вас не всегда есть один и тот же файл, может быть обновлен текстовый файл или таблица базы данных, которая всегда проверяет имена файлов, а затем выполняет проверку процессов и затем выполняет процесс убивает и удаляет на нем, как я описываю в следующем варианте. Обратите внимание, что вам потребуется имя пользователя и пароль учетной записи с правами администратора на данном компьютере, конечно, для выполнения удаления и завершения процессов.
4а. Когда вы не знаете, будет ли файл использоваться, когда вы пытаетесь его сохранить, вы можете закрыть все процессы, которые могут его использовать, например Word, если это документ Word, перед сохранением.
Если это локально, вы можете сделать это:
Если он удален, вы можете сделать это:
где txtUserName находится в форме DOMAIN\user .
Обратите внимание, что file должен быть UNC-путём: \\computer\share\yourdoc.docx чтобы Process мог определить, на каком компьютере он и p.MachineName будет действительным. Ниже приведен класс, который использует эти функции, что требует добавления ссылки на System.Management :
Есть несколько основных вещей, чтобы избежать этого, как уже упоминалось в других ответах:
В операциях FileStream поместите его в блок using с режимом доступа FileShare.ReadWrite .
Обратите внимание, что FileAccess.ReadWrite невозможен, если вы используете FileMode.Append .
Я столкнулся с этой проблемой, когда я использовал поток ввода, чтобы сделать File.SaveAs когда файл использовался. В моем случае я обнаружил, что мне вообще не нужно было сохранять его обратно в файловую систему, поэтому я просто удалил его, но, возможно, я мог попытаться создать FileStream в операторе using с FileAccess.ReadWrite , очень похоже на код выше.
Сохраните ваши данные в другом файле и вернитесь, чтобы удалить старый, если он больше не используется, а затем переименовать тот, который успешно сохранен, в имя исходного. Как вы проверяете файл, который используется, осуществляется с помощью
строка в моем коде ниже, и может быть сделано в службе Windows, в цикле, если у вас есть определенный файл, который вы хотите регулярно просматривать и удалять, когда вы хотите заменить его. Если у вас не всегда один и тот же файл, можно обновить текстовый файл или таблицу базы данных, чтобы служба всегда проверяла имена файлов, а затем выполняла эту проверку для процессов и впоследствии выполняла уничтожение и удаление процессов, как я описываю в следующем варианте. Обратите внимание, что вам понадобится имя пользователя и пароль учетной записи, которые имеют права администратора на данном компьютере, конечно, для выполнения удаления и завершения процессов.
Если вы не знаете, будет ли файл использоваться при попытке сохранить его, вы можете закрыть все процессы, которые могут его использовать, например, Word, если это документ Word, до сохранения.
Если это локально, вы можете сделать это:
Если он удаленный, вы можете сделать это:
где txtUserName находится в форме DOMAIN\user .
Допустим, вы не знаете имя процесса, который блокирует файл. Затем вы можете сделать это:
отладка
это может быть довольно легко решить (или очень трудно понять), в зависимости от конкретного сценария. Давайте посмотрим.
ваш процесс является единственным для доступа к файл
Вы уверены, что другое процесс-это ваш собственный процесс. Если вы знаете, что открыть файл в другой части вашей программы, то прежде всего вам нужно проверить, правильно ли закрыть файл handle после каждого использования. Вот пример кода с этой ошибкой:
к счастью FileStream осуществляет IDisposable , поэтому легко обернуть весь код внутри using о себе:
этот шаблон также гарантирует, что файл не будет оставлен открытым в случае исключений (возможно, по этой причине файл используется: что-то пошло не так, и никто не закрыл его; см. этот пост для примера).
обратите внимание на распространенную ошибку, которую мы видим очень часто на Сайте StackOverflow:
в этом случае ReadAllText() произойдет сбой, потому что файл используется ( File.Open() в строке до). Открывать файл заранее не только не нужно, но и неправильно. То же самое относится ко всем File функции, которые не возвращают дескриптор к файлу, с которым вы работаете: File.ReadAllText() , File.WriteAllText() , File.ReadAllLines() , File.WriteAllLines() и другие (например, File.AppendAllXyz() функции) все откроют и закроют файл сами по себе.
ваш процесс это не единственный доступ к этому файлу
Если ваш процесс не единственный для доступа к этому файлу, взаимодействие может быть сложнее. А шаблон повтора поможет (если файл не должен быть открыт кем-либо еще, но это так, то вам нужна утилита, такая как Process Explorer, чтобы проверить кто делает что).
способов избежать
при необходимости, всегда используйте используя заявления для открытия файлов. Как сказано в предыдущем абзаце он активно поможет вам избежать многих распространенных ошибок (см. этот пост пример как не использовать).
если возможно, попробуйте решить, кому принадлежит доступ к определенному файлу и централизовать доступ с помощью нескольких известных методов. Если, например, у вас есть файл данных, где ваша программа читает и записывает, то вы должны поместить весь код ввода-вывода в один класс. Это облегчит отладку (потому что вы всегда можете поставить точку останова там и посмотреть, кто что делает), а также это будет точка синхронизации (если требуется) для множественного доступа.
не забывайте, что операции ввода-вывода всегда может выйти из строя, например это:
если кто-то удаляет файл после File.Exists() но до File.Delete() , тогда он бросит IOException в месте, где вы можете ошибочно чувствовать себя в безопасности.
когда это возможно, примените шаблон повтора, и если вы используете FileSystemWatcher , рассмотрите возможность отсрочки действия (потому что вы получите уведомление, но приложение все еще может работать исключительно с этим файлом).
дополнительные сценарии
Это не всегда так просто, поэтому вам может потребоваться поделиться доступом с кем-то другим. Если, например, Вы читаете с начала и пишете до конца, у вас есть по крайней мере два варианта.
2) использовать FileShare перечисление для указания ОС разрешить другим процессам (или другим частям вашего собственного процесса) одновременно получать доступ к тому же файлу.
в общем N процессы могут читать из одного файла все вместе, но только один должен писать, в контролируемом сценарии вы можете даже включите параллельные записи, но это не может быть обобщено в нескольких текстовых абзацах внутри этого ответа.
можно разблокировать файл, используемый другим процессом? Это не всегда безопасно и не так просто, Но да,вполне возможно.
Читайте также: