System io ioexception процесс не может получить доступ к файлу
Способы избежать
Когда это применимо, всегда используйте с помощью операторов для открытия файлов. Как сказано в предыдущем абзаце, он будет активно помогать вам избежать многих распространенных ошибок (см. этот пост для примера на , как не использовать его).
Если возможно, попробуйте решить, кому принадлежит доступ к определенному файлу, и централизовать доступ с помощью нескольких известных методов. Если, например, у вас есть файл данных, в котором ваша программа читает и записывает, тогда вы должны вставить весь код ввода/вывода внутри одного класса. Это облегчит отладку (потому что вы всегда можете поставить точку останова и посмотреть, кто что делает), а также будет точкой синхронизации (если требуется) для множественного доступа.
Не забывайте, что операции ввода-вывода всегда могут быть провалены, например:
Если кто-то удалит файл после File.Exists() , но до File.Delete() , то он выкинет IOException в том месте, где вы можете ошибочно чувствовать себя в безопасности.
Когда это возможно, примените шаблон повтора, и если вы используете FileSystemWatcher , подумайте о переносе действия (потому что вы получите уведомление, но приложение все еще может работать исключительно с этим файлом).
Расширенные сценарии
Это не всегда так просто, поэтому вам может потребоваться предоставить доступ к кому-то другому. Если, например, вы читаете с самого начала и записываете до конца, у вас есть как минимум два варианта.
1) используют один и тот же FileStream с надлежащими функциями синхронизации (поскольку он не является потокобезопасным). См. this и для примера.
2) используйте перечисление FileShare , чтобы указать ОС, чтобы другие процессы (или другие части вашего собственного процесса) могли одновременно обращаться к одному и тому же файлу.
В этом примере я показал, как открыть файл для записи и поделиться для чтения; обратите внимание, что при чтении и записи перекрывается, это приводит к undefined или неверным данным. Это ситуация, которая должна решаться при чтении. Также обратите внимание, что это не делает доступ к потоку stream потокобезопасным, поэтому этот объект нельзя обменивать несколькими потоками, если доступ не синхронизирован каким-либо образом (см. Предыдущие ссылки). Доступны другие варианты совместного доступа, и они открывают более сложные сценарии. Подробнее см. MSDN.
В общем случае процессы N могут считывать из одного и того же файла все вместе, но только один должен писать, в контролируемом сценарии вы можете даже разрешать одновременные записи, но это не может быть обобщено в нескольких текстовых абзацах внутри этого ответа.
Можно ли разблокировать файл, используемый другим процессом? Это не всегда безопасно и не так просто, но да, это возможно.
Использование FileShare исправило мою проблему открытия файла, даже если он открывается другим процессом.
Возникла проблема при загрузке изображения и не удалось удалить его и найти решение. gl hf
Я получил эту ошибку, потому что я делал File.Move до пути к файлу без имени файла, вам нужно указать полный путь в пункте назначения.
У меня был следующий сценарий, который вызывал ту же ошибку:
- Загрузка файлов на сервер
- Затем избавиться от старых файлов после их загрузки
Большинство файлов были маленькими по размеру, однако некоторые из них были большими, поэтому попытка удалить те, которые привели к невозможности доступа к ошибке файла.
Было нелегко найти, однако, решение было так же просто, как “Ожидание” “для выполнения задачи”:
Как указывалось в других ответах в этом потоке, для устранения этой ошибки вам необходимо тщательно проверить код, чтобы понять, где файл заблокирован.
В моем случае я отправлял файл в виде вложения электронной почты перед выполнением операции перемещения.
Таким образом, файл был заблокирован на пару секунд, пока клиент SMTP не завершил отправку электронной почты.
Другое возможное решение, как было указано ранее Хадсоном, было бы уничтожить объект после использования.
Ошибка указывает, что другой процесс пытается получить доступ к файлу. Возможно, вы или кто-то еще открываете его, пока вы пытаетесь написать ему. “Чтение” или “Копировать” обычно не вызывает этого, но запись на него или вызов delete на нем будут.
Есть некоторые основные вещи, чтобы избежать этого, как упомянули другие ответы:
- В операциях FileStream поместите его в using блок с помощью режима доступа FileShare.ReadWrite .
Обратите внимание, что FileAccess.ReadWrite невозможен, если вы используете FileMode.Append .
Я столкнулся с этой проблемой, когда я использовал входной поток для File.SaveAs файла File.SaveAs когда файл использовался. В моем случае я обнаружил, что мне фактически не нужно было сохранять его обратно в файловую систему вообще, поэтому я просто удалил это, но я, возможно, попытался создать FileStream в операторе using с FileAccess.ReadWrite , как код выше.
Сохранение ваших данных в виде другого файла и возврат к удалению старого, когда оно больше не используется, переименование того, которое было успешно сохранено на имя исходного, является опцией. Как вы проверяете используемый файл, выполняется через List lstProcs = ProcessHandler.WhoIsLocking(file); строка в моем коде ниже и может быть выполнена в службе Windows в цикле, если у вас есть определенный файл, который вы хотите регулярно смотреть и удалять, когда хотите его заменить. Если у вас не всегда есть один и тот же файл, может быть обновлен текстовый файл или таблица базы данных, которая всегда проверяет имена файлов, а затем выполняет проверку процессов и затем выполняет процесс убивает и удаляет на нем, как я описываю в следующем варианте. Обратите внимание, что вам потребуется имя пользователя и пароль учетной записи с правами администратора на данном компьютере, конечно, для выполнения удаления и завершения процессов.
4а. Когда вы не знаете, будет ли файл использоваться, когда вы пытаетесь его сохранить, вы можете закрыть все процессы, которые могут его использовать, например Word, если это документ Word, перед сохранением.
Если это локально, вы можете сделать это:
Если он удален, вы можете сделать это:
где txtUserName находится в форме DOMAIN\user .
4b. Скажем, вы не знаете имя процесса, которое блокирует файл… вы можете сделать это:
Обратите внимание, что 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 .
Допустим, вы не знаете имя процесса, который блокирует файл. Затем вы можете сделать это:
Обратите внимание, что file должен иметь UNC-путь: \\computer\share\yourdoc.docx чтобы Process мог определить, на каком компьютере он работает, и p.MachineName чтобы быть действительным.
Ниже приведен класс, используемый этими функциями, который требует добавления ссылки на System.Management . Код был изначально написан Эриком Дж.:
Это будет самый простой способ,
Thread.sleep поможет отлично работать, иначе это повлияет на следующий шаг, если мы будем копировать или записывать файл.
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Исключение, которое выдается при возникновении ошибки ввода-вывода.
Свойства
Возвращает коллекцию пар «ключ-значение», предоставляющую дополнительные сведения об исключении.
Получает имя файла, который не удается найти.
Возвращает имя журнала, в котором описано, почему закончилась неудачей загрузка сборки.
Получает или задает ссылку на файл справки, связанный с этим исключением.
Возвращает или задает HRESULT — кодированное числовое значение, присвоенное определенному исключению.
Возвращает экземпляр класса Exception, который вызвал текущее исключение.
Возвращает или задает имя приложения или объекта, вызывавшего ошибку.
Получает строковое представление непосредственных кадров в стеке вызова.
Возвращает метод, создавший текущее исключение.
Методы
Определяет, равен ли указанный объект текущему объекту.
При переопределении в производном классе возвращает исключение Exception, которое является первопричиной одного или нескольких последующих исключений.
Служит хэш-функцией по умолчанию.
Устанавливает объект SerializationInfo с именем файла и дополнительными сведениями об исключении.
При переопределении в производном классе задает объект SerializationInfo со сведениями об исключении.
Возвращает тип среды выполнения текущего экземпляра.
Создает неполную копию текущего объекта Object.
Комментарии
FileNotFoundException использует COR_E_FILENOTFOUND HRESULT, имеющий значение 0x80070002.
Методы
Определяет, равен ли указанный объект текущему объекту.
При переопределении в производном классе возвращает исключение Exception, которое является первопричиной одного или нескольких последующих исключений.
Служит хэш-функцией по умолчанию.
При переопределении в производном классе задает объект SerializationInfo со сведениями об исключении.
Возвращает тип среды выполнения текущего экземпляра.
Создает неполную копию текущего объекта Object.
Создает и возвращает строковое представление текущего исключения.
6 Answers 6
You will have to close the file after editing it.
After closing it you can again use it(for reading)
The process of working with files is that, 1) Create 2) Open 3) Write/Read 4) Close. So, I don't see why it won't work.. Even after your second function i.e. Reading the text file you'll have to close it.
The issue is sometimes file locks don't get released immediately after they are closed.
You can try run a loop to read the file. Inside the loop put a try catch statement and if the file reads successfully break from the loop. Otherwise, wait a few milliseconds and try to read the file again:
i like this approach, but I would avoid using while(true) in logic like this. In the case that ANY error is thrown during the reading of a file this will continue to retry. So assuming the case where the failure mode is systematic and not random this would create an infinite loop.
i like this approach, but I would avoid using while(true) in logic like this. In the case that ANY error is thrown during the reading of a file this will continue to retry. So assuming the case where the failure mode is systematic and not random this would create an infinite loop.
after writing your text file, you should close it first before proceeding to your second function:
Just to elaborate:
The point is, you have to close the FileStream after you are done with any operations with your file. You can do this via myFileStream.Close() .
Moreover, File.Create(filename) returns a FileStream object which you can then Close() .
What if the stream you are using has to be passed to another library? I have to pass my streamwriter to a JsonTextWriter (Newtonsoft.Json) to write out results.
Actually this is not a problem of closing/disposing the stream, File.WriteAllText and File.ReadAllText does that internally.
The issue is because a wrong use of the async/await pattern. GET is async but never awaited, thus causing function1 to finish and move on to function2 before all content was actually written to the file.
The way it is written GET is not awaitable because it is async void which should never be used unless you're dealing with event or really know what you're doing.
So, either remove the use of async/await completely or be async all the way:
События
Возникает, когда исключение сериализовано для создания объекта состояния исключения, содержащего сериализованные данные об исключении.
Обработка исключений при операциях ввода-вывода
По причине зависимости от операционной системы иногда идентичные условия (например, отсутствие указанного каталога) могут создавать в методах ввода-вывода любое исключение из класса ввода-вывода. Это означает, что при вызове интерфейсов API ввода-вывода ваш код должн быть готов обработать все такие исключения или большую их часть, как показано в следующей таблице:
События
Возникает, когда исключение сериализовано для создания объекта состояния исключения, содержащего сериализованные данные об исключении.
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Исключение, которое выдается при попытке получить доступ к файлу или каталогу, которых нет на диске.
Примеры
Этот пример кода является частью более крупного примера, предоставленного FileStream.Lock для метода.
Свойства
Возвращает коллекцию пар «ключ-значение», предоставляющую дополнительные сведения об исключении.
Получает или задает ссылку на файл справки, связанный с этим исключением.
Возвращает или задает HRESULT — кодированное числовое значение, присвоенное определенному исключению.
Возвращает экземпляр класса Exception, который вызвал текущее исключение.
Возвращает или задает имя приложения или объекта, вызывавшего ошибку.
Получает строковое представление непосредственных кадров в стеке вызова.
Возвращает метод, создавший текущее исключение.
Конструкторы
Инициализирует новый экземпляр класса FileNotFoundException с указанными данными о сериализации и контексте.
Отладка
Это может быть довольно легко решить (или довольно трудно понять), в зависимости от вашего конкретного сценария. Посмотрим на некоторые.
Ваш процесс доступен только для доступа к этому файлу
Вы уверены, что другой процесс – это ваш собственный процесс. Если вы знаете, что вы открываете этот файл в другой части вашей программы, то прежде всего вам нужно проверить, правильно ли вы закрываете дескриптор файла после каждого использования. Вот пример кода с этой ошибкой:
К счастью, FileStream реализует IDisposable , поэтому легко обернуть весь ваш код внутри инструкции using :
Этот шаблон также гарантирует, что файл не останется открытым в случае исключений (может быть, причина в том, что файл используется: что-то пошло не так, и никто его не закрыл, см. этот пост для примера).
Обратите внимание на общую ошибку, которую мы часто видим в StackOverflow:
В этом случае ReadAllText() будет терпеть неудачу, потому что файл используется ( File.Open() в строке перед). Чтобы открыть файл заранее, это не только лишний, но и неправильный. То же самое относится ко всем функциям File , которые не возвращают дескриптор файла, с которым вы работаете: File.ReadAllText() , File.WriteAllText() , File.ReadAllLines() , File.WriteAllLines() и другие (например, функции File.AppendAllXyz() ) будут все открывают и закрывают файл самостоятельно.
Ваш процесс не является единственным для доступа к этому файлу
Если ваш процесс не является единственным для доступа к этому файлу, то взаимодействие может быть сложнее. Шаблон повторения поможет (если файл не должен открываться кем-либо другим, но он есть, то вам нужна утилита, например Process Explorer, чтобы проверить, кто что делает).
Комментарии
Класс IOException является базовым классом для исключений, возникающих при доступе к данным с помощью потоков, файлов и каталогов.
Библиотека базовых классов включает следующие типы, каждый из которых является производным классом IOException :
При необходимости используйте эти типы вместо IOException.
IOException использует COR_E_IO HRESULT, имеющий значение 0x80131620.
Сопоставление кодов ошибок с исключениями
Например, при вызове метода в операционной системе Windows код ошибки ERROR_FILE_NOT_FOUND (или 0x02) преобразуется в исключение FileNotFoundException, а код ошибки ERROR_PATH_NOT_FOUND (или 0x03) — в DirectoryNotFoundException.
К сожалению, точные условия возникновения определенных кодов ошибок в операционной системе часто не документируются или документируются в недостаточном объеме. Это означает, что возможны непредвиденные исключения. Например, при работе с каталогом логично ожидать, что передача недопустимого пути в конструктор DirectoryInfo приведет к созданию исключения DirectoryNotFoundException. Но в этой ситуации может создаваться и FileNotFoundException.
Обработка IOException
IOException является базовым классом для исключений в пространстве имен System.IO и создается для любого кода ошибки, который не имеет сопоставления с определенным типом исключения. Это означает, что оно может появиться в любой операции ввода-вывода.
Так как IOException является базовым классом для других типов исключений в пространстве имен System.IO, его нужно обрабатывать в блоке catch после обработки других исключений, связанных с вводом-выводом.
Обратите внимание, что в коде обработки исключений IOException всегда нужно обрабатывать последним. Иначе блоки catch для производных классов не проверяются, ведь это исключение является базовым классом для всех остальных.
В случае IOException можно получить дополнительные сведения об ошибке из свойства IOException . Чтобы преобразовать значение HResult в код ошибки Win32, отбросьте верхние 16 бит из 32-разрядного значения. В приведенной ниже таблице перечислены коды ошибок, которые могут быть заключены в IOException.
HResult | Константа | Описание |
---|---|---|
ERROR_SHARING_VIOLATION | 32 | Отсутствует имя файла, или файл или каталог уже используется. |
ERROR_FILE_EXISTS | 80 | Файл уже существует. |
ERROR_INVALID_PARAMETER | 87 | Методу передан недопустимый аргумент. |
ERROR_ALREADY_EXISTS | 183 | Файл или каталог уже существует. |
Для обработки этих исключений можно применить предложение When в инструкции catch, как показано в приведенном ниже примере.
I am new to programming and I have a question. If I have two functions, one creates a text file and writes into it, while the other opens the same text file and reads from it.
The error I get is:
System.IO.IOException: 'The process cannot access the file '@.txt' because it is being used by another process.'
I have tried setting seperate timers to each of the functions but it still does not work. I think the best way would be that the function two does not start until function one ends.
Can you help me achieve this? Thank you very much! Mike
The code is very long and messy. Basically one function saves data to text file, then the other function comes in and reads from the file. The whole process repeats again and again and again. My code is beginner and very messy.
Конструкторы
Инициализирует новый экземпляр класса IOException с указанными данными о сериализации и контексте.
Читайте также: