Close закрыть файл


Принудительно закрыть файл по его пути в Windows

Я пишу временный файловый менеджер для других разработчиков. Я хочу удалить файлы, даже если наши консольные приложения зависают или закрываются кнопкой «X».

Пока нашел std::set_terminate , std::atexit а также SetConsoleCtrlHandler методы, с помощью которых я могу удалить все временные файлы, которые мне нужны. Проблема в том, что я не могу удалить открытые файлы. Более того — я не могу управлять потоками для этих файлов, потому что разработчики используют несколько библиотек (например, GDAL), которые используют свои собственные механизмы потоков и могут принимать только путь к целевому файлу.

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

Решение

Вам необходимо закрыть файловые дескрипторы, принадлежащие вашему текущему процессу. Сделать это:

  • Использовать NtQuerySystemInformation API с недокументированным SystemHandleInformation параметр.
  • Это дает вам массив всех дескрипторов, открытых в системе
  • Выполните итерацию по массиву и выберите только те, которые соответствуют PID вашего процесса и являются файловыми дескрипторами
  • Вы можете затем сузить его, используя GetFinalPathNameByHandle получить пути к открытым файлам, например, Вы можете выбрать конкретные имена файлов или все файлы с tmp во имя
  • Для любых файлов, которые вы хотите удалить, позвоните CloseHandle() заставить закрыть ручку, то конечно DeleteFile() на пути.

Некоторый код (без какой-либо проверки ошибок):

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

Есть хороший пример кода Вот .

Другие решения

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

Напишите приложение для запуска, которое выполняет всю очистку.
Панель запуска вызывает CreateProcess и WaitForSingleObject для процесса
справиться. Дескриптор процесса сигнализируется независимо от того, как процесс
завершается (чистое отключение, сбой и т. д.). Вам не нужно беспокоиться
о принудительном закрытии файлов — ОС закрывает все дескрипторы, удерживаемые
процесс по окончании процесса.

Метод Workbook. Close (Excel) Workbook.Close method (Excel)

Закрывает объект. Closes the object.

Синтаксис Syntax

Expression. Close (закрыть ) (SaveChanges, filename, раутеворкбук) expression.Close (SaveChanges, FileName, RouteWorkbook)

Expression (выражение ) Переменная, представляющая объект Workbook . expression A variable that represents a Workbook object.

Параметры Parameters

Имя Name Обязательный или необязательный Required/Optional Тип данных Data type Описание Description
SaveChanges SaveChanges Необязательный Optional Variant Variant Если в книгу нет изменений, этот аргумент игнорируется. If there are no changes to the workbook, this argument is ignored. Если книга содержит изменения, а книга отображается в других открытых окнах, этот аргумент игнорируется. If there are changes to the workbook and the workbook appears in other open windows, this argument is ignored. Если книга содержит изменения, но она не отображается в других открытых окнах, этот аргумент указывает, следует ли сохранить изменения. If there are changes to the workbook but the workbook doesn’t appear in any other open windows, this argument specifies whether changes should be saved. Если задано значение true, изменения сохраняются в книге. If set to True, changes are saved to the workbook.

Если имя файла, связанное с книгой, еще не задано, используется имя файла . If there is not yet a file name associated with the workbook, FileName is used. Если параметр filename опущен, пользователю предлагается указать имя файла. If FileName is omitted, the user is asked to supply a file name. FileName FileName Необязательный Optional Variant Variant Сохраняет изменения под этим именем файла. Saves changes under this file name. Раутеворкбук RouteWorkbook Необязательный Optional Variant Variant Если книга не должна маршрутизироваться следующему получателю (если она не имеет маршрута или уже была перенаправлена), этот аргумент игнорируется. If the workbook doesn’t need to be routed to the next recipient (if it has no routing slip or has already been routed), this argument is ignored. В противном случае Microsoft Excel перенаправляет книгу в соответствии со значением этого параметра. Otherwise, Microsoft Excel routes the workbook according to the value of this parameter.

Если задано значение true, книга отправляется следующему получателю. If set to True, the workbook is sent to the next recipient. Если задано значение false, книга не отправляется. If set to False, the workbook is not sent. Если этот параметр не задан, пользователю предлагается указать, следует ли отправить книгу. If omitted, the user is asked whether the workbook should be sent.

Примечания Remarks

При закрытии книги из Visual Basic макросы Auto_Close не выполняются в книге. Closing a workbook from Visual Basic doesn’t run any Auto_Close macros in the workbook. Используйте метод рунаутомакрос для запуска макросов AUTO_CLOSE. Use the RunAutoMacros method to run the Auto_Close macros.

Пример Example

В этом примере закрывается book1. xls и удаляются все внесенные в него изменения. This example closes Book1.xls and discards any changes that have been made to it.

Поддержка и обратная связь Support and feedback


Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Have questions or feedback about Office VBA or this documentation? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь. Please see Office VBA support and feedback for guidance about the ways you can receive support and provide feedback.

Как закрыть файл?

я чувствовал себя в мире с POSIX после многих лет опыта.

тогда я прочитал этой сообщение от Лайнуса Торвальдса, около 2002 года:

(b) не текущая практика

«не портативный» часть исходит из того, что (как кто-то указал out), a потоковая среда, в которой ядро тут закройте FD при ошибках FD, возможно, был действительно повторно использован (ядром) для какой-то другой поток, и закрытие FD во второй раз является ошибкой.

не только цикл пока EBADF непортящийся, но любой цикл, из-за состояния гонки, которое я, вероятно, заметил бы, если бы я не «заключил мир», принимая такие вещи как должное.

однако в реализации стандартной библиотеки GCC C++ , basic_file_stdio.cc , мы

основной целью этой библиотеки является Linux, но, похоже, она не обращает внимания на Линуса.

насколько я понял, EINTR происходит только после системного вызова блоки, что означает, что ядро получило запрос на освобождение дескриптора перед началом любой прерванной работы. Так что нет необходимости делать петлю. Действительно, SA_RESTART поведение сигнала не применяется к close и генерировать такой цикл по умолчанию, именно потому, что это небезопасно.

это стандартная ошибка библиотеки, верно? На каждом файле, когда-либо закрытом приложением C++.

EDIT: чтобы не вызывать слишком много тревоги, прежде чем какой-то гуру придет с ответом, я должен отметить, что close только, кажется, разрешено блокировать при определенных обстоятельствах, возможно, ни один из которых никогда не применяется к обычным файлам. Я не совсем понимаю все детали, но вы не должны видеть EINTR от close не выбирая во что-то fcntl или setsockopt . Тем не менее такая возможность делает общий библиотечный код более опасным.

1 ответов

относительно POSIX,Р.. ‘ s ответ на вопрос предельно ясно и лаконично: close() — это особый случай без перезапуска, и цикл не должен использоваться.

это не ответ. Рассмотрим это больше как мнение коллеги-программиста, включая рассуждения, стоящие за этим мнение.

POSIX.1-2001 и POSIX.1-2008 опишите три возможных значения errno, которые могут возникнуть: EBADF , EINTR и EIO . Состояние дескриптора после EINTR и EIO is «не указано», что означает, что он может или не может быть закрыт. EBADF указано fd не является допустимым дескриптором. Другими словами, POSIX.1 явно рекомендует использовать

без каких-либо повторных циклов для закрытия файла дескрипторы.

(даже группа Остина дефект #519 Р.. упомянуто, не помогает с восстановлением от close() ошибки: он оставляет его неопределенным, возможен ли какой-либо ввод-вывод после EINTR ошибки, даже если сам дескриптор остается открытым.)

для Linux close() syscall определяется в fs / open.c С __do_close() на fs / file.c управление блокировкой таблицы дескрипторов и filp_close() обратно в fs / open.c заботясь о деталях.

в итоге запись дескриптора удаляется из таблицы безоговорочно первый, за которым следует специфичная для файловой системы промывка ( f_op->flush() ), а затем уведомление (dnotify/fsnotify крюк), и, наконец, путем удаления любой записи или блокировки файлов. (Большинство локальных файловых систем, таких как ext2, ext3, ext4, xfs, bfs, tmpfs и т. д., не имеют ->flush() , поэтому, учитывая действительный дескриптор, close() не может потерпеть неудачу. Только ecryptfs, exofs, предохранитель, cifs и nfs имеют ->flush() обработчики в Linux-3.13.6, насколько я могу сказать.)

это означает, что в Linux, если ошибка записи происходит в файловой системе ->flush() проводник в close() , невозможно повторить попытку; дескриптор файла всегда закрыт, как и сказал Торвальдс.

В FreeBSD close() man page описывает точно такое же поведение.

ни в OpenBSD ни the Mac OS X close() man-страницы описывают, закрыт ли дескриптор в случае ошибок, но я считаю, что они разделяют поведение FreeBSD.

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

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

другие errno значения указывают на ошибку при завершении состояния файла. В Linux это определенно ошибка, связанная с сбросом любых оставшихся данных в фактическое хранилище. В частности, я могу себе представить ENOMEM в случае, если нет места в буфере данных, EIO если данные не могут быть отправлены или записаны на фактическое устройство или носитель, EPIPE если соединение с хранилище было потеряно, ENOSPC если хранилище уже заполнено без резервирования для незаполненных данных и так далее. Если файл является файлом журнала, я бы сообщил о сбое процесса и вышел изящно. Если содержимое файла по-прежнему доступно в памяти, я бы удалил (отсоединил) весь файл и повторил попытку. В противном случае я бы сообщил об ошибке пользователю.

(помните, что в Linux и FreeBSD вы не «сливаете» файловые дескрипторы в случае ошибки; они гарантированно будут закрыты даже при возникновении ошибки. Я предполагаю, что все другие операционные системы, которые я могу использовать, ведут себя одинаково.)

вспомогательная функция, которую я буду использовать с этого момента, будет чем-то вроде


я знаю, что выше безопасно на Linux и FreeBSD, и я предполагаю, что это безопасно на всех других POSIX-y системах. Если я столкнусь с тем, что нет, я могу просто заменить вышеуказанную версию пользовательской версией, обернув ее в подходящую #ifdef для этой ОС. Причина этого утверждает errno без изменений просто причуда моего стиля кодирования; он делает пути ошибок короткого замыкания короче (менее повторяющийся код).

если я закрываю файл, содержащий важную информацию о пользователе, я сделаю fsync() или fdatasync() на нем до закрытия. Это обеспечивает попадание данных в хранилище, но также вызывает задержку по сравнению с нормальной работой; поэтому я не буду делать это для обычных файлов данных.

если я не буду unlink() ing закрытый файл, я проверю closefd() возвращаемое значение, и действовать соответственно. Если я смогу легко повторить попытку, я сделаю это, но не более одного или двух раз. Для файлов журналов и сгенерированных/потоковых файлов я только предупреждаю пользователя.

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

Как закрыть файл?

Современные операционные системы и, в частности, популярная OS Windows предлагает немало способов, как закрыть файл. О них мы и поговорим в данной статье.

Самым простым и доступным методом является использование кнопки «Х», которая располагается в верхнем правом углу практически любого открытого окна. Для этого достаточно кликнуть по ней левой кнопкой мыши. Если этот способ вам не подходит можно прибегнуть к сочетанию клавиш «ALT+F4». Одновременное нажатие этих кнопок также приведет к закрытию активного окна.

Еще одним способ закрытия ненужных программ может быть использование диспетчера задач. Как правило, к нему прибегают в случае, если открытый файл недоступен или не отвечает. Вызвать диспетчер можно кликнув, к примеру, по «Рабочему столу» правой кнопкой мыши и выбрав в открывшемся меню одноименную строчку. Если компьютер завис, попробуйте комбинацию «CTRL+ALT+DEL». В принципе, способов вызвать диспетчер задач немало, мы описали самые быстрые.

После того, как окно диспетчера открылось в нем нужно выбрать вкладку «Приложения». Там вы увидите полный список запущенных программ. Выберите ту, которую нужно закрыть и выделите ее щелчком левой кнопки мыши. После этого кликните по кнопке «Снять задачу». Вот и всё, проблемное приложение принудительно будет закрыто.

Как закрыть файл в system

Иногда случается так, что вы хотите провести какую-либо операцию с файлом, но на экране выскакивают диалоги типа «Файл открыт в system» или «Файл открыт в проводнике». Это значит, что элемент, который вы собираетесь закрыть, открыт служебной программой. В диспетчере служебные приложения не отображаются. Решает эту проблему проверенный годами способ – перезагрузка компьютера. Единственное, перезагрузка может не помочь, если, к примеру, в настройках программы, создающей виртуальные приводы отмечен пункт «Автомонтироание». Поэтому, прежде чем перезагружаться, уберите соответствующую птичку в Daemon Tools или подобной программе для виртуальных дисков.

Теперь вы знаете, не только простые способы закрытия окон, но и то, как закрыть файл в проводнике. Удачи!

закрыть файл с fclose (), но файл все еще в использовании

December 2020

10.5k раз

У меня есть проблема с удаления / перезаписи файла с помощью моей программы, которая также используется (чтение) по моей программе. Проблема, кажется, что из-за того, мою программа читают данные из файла (output.txt) он помещает файл в «в использовании» состояния, что делает его невозможно удалить или перезаписать файл.

Я не понимаю, почему файл остается «в работе», потому что я закрыть файл после использования с fclose ();

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

Что такое решение, чтобы освободить файл, поэтому он может быть удален / перезаписан?

На самом деле мой код не петля без конца; )

Обновить

Как задать часть моего кода, который также создает файл «в работе». Это не цикл, и эта функция вызывается из основных ();

Цикл в то время как синтаксический анализ файла. Output.txt содержит наборы 9 переменных, число наборов неизвестно, но всегда в наборах 9.

output.txt может содержать, например: 0,1,2,3,4,5,6,7,8,8,7,6,5,4,1,2,3,0

обновление 2

извините за использование предварительно еще раз, но я не получаю форматирование этого сайта :(

Как удалить открытый файл – все способы

Бывают ситуации, когда пользователь хочет закрыть или удалить какой-то файл, но не может этого сделать, так как он «открыт в другой программе» и тогда он начинает искать информацию о том, как этот открытый файл удалить.


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

Через командную строку

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

Делается это следующим образом:

  1. В меню «Пуск» («Windows») открыть «Все программы» и в разделе «Стандартные» найти пункт «Командная строка».
  2. Нажать на данном пункте правой кнопкой мыши и выбрать «Запуск от имени администратора».
    Затем в командной строке необходимо ввести такую команду:

net file [название файла] /close

К примеру, если запущенный файл называется «geek-nose.exe», то данная команда будет выглядеть вот так: net file geek-nose.exe /close

Открытие командной строки от имени администратора ввод команды для закрытия файла geek-nose.exe

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

Через диспетчер задач

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

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

Чтобы открыть диспетчер задач, нужно нажать Ctrl+Alt+Delete или же Win+X и в списке вариантов выбрать «Диспетчер задач».

Также можно нажать на нижней панели правой кнопкой мыши и в выпадающем меню выбрать «Запустить диспетчер задач».

Во вкладке «Приложения» нужно найти нужный файл и нажать на кнопку «Снять задачу». Также можно нем кликнуть правой кнопкой мыши.

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

Запуск диспетчера задач и снятие задачи

После этого нужно снова попробовать удалить файл.

Если он все еще не удаляется, можно попробовать нажать на пункт «Завершить дерево процессов».

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

С помощью меню «Управление компьютером»

Данный способ подразумевает выполнение следующих действий:

  1. Запускаем меню «Управление компьютером». Легче всего сделать это с помощью поиска в меню «Пуск» («Windows»).
  2. В меню слева открываем сначала «Служебные», затем «Общие папки» и «Открытые файлы».
  3. В открывшемся меню нужно нажать правой кнопкой мыши и выбрать пункт «Отключить все открытые файлы».

Поиск меню «Управление компьютером» и отключение всех открытых файлов в нем

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

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


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

Внимание: Даже если в папке «Открытые файлы» меню «Управление компьютером» не отображается ничего, все равно нужно нажать правой кнопкой мыши и выбрать пункт «Отключить…».

Теперь можно снова попытаться удалить файл.

Unlocker

Эта маленькая утилита очень удобна в использовании и позволяет за считанные секунды удалять файлы, открытые в другой программе. Скачать её можно на официальном сайте. После установки она будет интегрирована в контекстное меню (то, которое открывается по нажатию правой кнопкой мыши на любом файле или папке). Чтобы воспользоваться Unlocker для удаления открытых файлов, необходимо сделать следующее:

  1. Нажать на файле, который не удаляется, правок кнопкой мыши. Выбрать пункт «Unlocker».
  2. Среди действий выбрать «Удалить». Также можно нажать кнопки «Удалить процесс» или «Разблокировать все».

Процесс использования Unlocker

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

С помощью DeadLock

В последнее время вместе с Unlocker устанавливается огромное количество нежелательных программ и даже вирусов. Это касается даже установщика с официального сайта. Кроме того, все чаще Unlocker стали блокировать антивирусы и фаерволы. Поэтому DeadLock выглядит очень достойной альтернативой. Скачать её можно, к примеру, здесь. Дальше нужно сделать следующее:

  1. Перетащить курсором мыши нужный файл в окно программы.
  2. Нажать на нем правой кнопкой мыши и выбрать пункт «Unlock», затем еще раз «Unlock» или же «Delete», чтобы сразу его и удалить.

Использование DeadLock для разблокировки и удаления файлов

Удаление в безопасном режиме

Также можно попытаться удалить файл при загруженной в безопасном режиме системе. Для того, чтобы запустить её таким образом, необходимо при запуске компьютера нажать кнопку F8 и в списке вариантов выбрать то, что связано с безопасным режимом. В большинстве случаев он так и называется, «Безопасный режим».

Выбор варианта «Безопасный режим» при загрузке системы

Дальше процесс выглядит точно так же, как и раньше – нажимаем на файле правой кнопкой мыши и выбираем «Удалить».

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

С помощью загрузочного диска или флешки

Этот способ очень похож на предыдущий. Только здесь мы запускаем систему через безопасный режим, а через загрузочный диск (он же LiveCD).

Сейчас в интернете можно скачать множество подобных образов. Их достаточно записать на флешку или CD/DVD диск и загрузиться с него. Этот этап в данном случае самый сложный – нужно запустить boot menu и выбрать там загрузку с флешки/диска.

Для этого вставьте в компьютер носитель информации, перезагрузите его и смотрите подсказки относительно запуска boot menu.

В большинстве случаев где-то будет написано примерно следующее: «Press F5 to run boot menu». Соответственно, в таком случае нужно нажимать F5.

После этого появится меню, в котором и нужно указать, с чего будет загружаться система. В нашем примере это «Flash drive…».

Узнать нужный вариант очень просто – если это флешка, то в названии будет фигурировать слово «flash», а если диск, то «CD» или «DVD».

Один из вариантов запущенного boot menu

Дальше произойдет загрузка с загрузочной флешки или диска. Интерфейс LiveCD может быть похож на Windows или Ubuntu, но в любом случае по нажатию на файл правой кнопкой мыши можно будет видеть пункт «Удалить», «Delete» или «Cut».


Пользователю остается только нажать на один из них.

Более простые варианты

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

  1. Перезагрузите компьютер. Вполне возможно, что после перезагрузки все процессы будут завершены, в том числе и тот, в котором открыт предназначенный для удаления файл.
  2. Удалите программу, с помощью которой открывается данный файл. После этого все процессы, связанные с ней, тоже будут автоматически завершены.
  3. Выполните полную проверку компьютера на вирусы. В некоторых случаях файл не закрывается из-за банального вируса и после удаления такового все становится на свои места.
  4. Отключите антивирус. Бывает такое, что некоторые файлы блокируются не системой, а антивирусной программой. Соответственно, тогда прекращение его работы помогает спокойно работать с файлом.
  5. Войдите в систему как администратор. Иногда файл невозможно удалить из-за нехватки прав у пользователя.
  6. Просто переместите файл в другую папку.
  7. Попробуйте откатить систему до того момента, когда файл свободно открывался и удалялся. Для этого зайдите в «Панель управления», выберите «Восстановление», затем нажмите «Запуск восстановления системы».
  8. После этого следует кликнуть на нужный вариант бэкапа (легко сориентироваться по времени создания) и нажмите «Далее».

Процесс восстановления системы

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

Зачем использовать close() для закрытия файла?

Я изучаю некоторые функции файлов и, следовательно, сомневаюсь.

Мне интересно, что вам нужно позвонить close() , чтобы закрыть файл? Если я не позвонил close() после прочтения/записи файла, что может случиться? И если я позвоню close() , могу ли я использовать дескриптор файла?

Создан 19 июн. 12 2012-06-19 06:24:39 Shen

Куча ответов ниже говорит, что close() сбрасывает буферы на диск. Однако close() является функцией POSIX, и это не относится к POSIX close(). Он только освобождает блокировки и освобождает ресурсы. – Jim Balter 19 июн. 12 2012-06-19 10:51:20

6 ответов

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

Если ОС имеет ограниченные ресурсы (например, количество открытых файлов), то, не закрывая файлы, вы тратите ресурсы системы.

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

Создан 19 июн. 12 2012-06-19 06:27:51 John3136

Несколько ответов здесь утверждают, что буферы очищаются при закрытии(), но на самом деле это неверно . POSIX close() не смывает и не имеет никакого отношения к тому, записаны ли данные на устройство или когда они записаны. – Jim Balter 19 июн. 12 2012-06-19 11:04:20

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

И никогда не используйте дескриптор уже закрытого файла. Это не имеет смысла.

Создан 19 июн. 12 2012-06-19 06:26:46 Maksym Polshcha

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

Создан 19 июн. 12 2012-06-19 06:27:51 Manik Sidana

write() копирует данные из пользовательского пространства в системные буферы. Буферы системы будут очищены при удобстве системы или при синхронизации(). close() имеет * отсутствие подшипника * при промывке буферов. Он только освобождает блокировки файлов и освобождает ресурсы. – Jim Balter 19 июн. 12 2012-06-19 11:16:25

Закрытие файла: Когда это делается с файлом, его необходимо закрыть с помощью функции fclose().

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

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


(Буфер действительно только 1-мерным, несмотря на этот рисунок.)

Когда буфер заполняется (или когда файл закрыт), данные, наконец, записываются на диск.

Создан 19 июн. 12 2012-06-19 06:29:26 Hrishikesh

Небольшие исправления. Ваш ответ _seems_, чтобы указать, что файлы должны быть закрыты только с помощью ‘fclose’. Вы также можете закрыть файлы с помощью ‘close’. Его просто, что ‘fclose’ принимает указатель файла, а’ close’ принимает дескриптор файла. Кроме того, многие реализации стирают буфер, когда они сталкиваются с символом новой строки ‘\ n’ – Pavan Manjunath 19 июн. 12 2012-06-19 06:38:44

Спасибо за исправления. :)Hrishikesh 19 июн. 12 2012-06-19 06:41:41

Вопрос о close(), а не fclose(). Ничто из того, что вы написали здесь, на самом деле верно для close(). И утверждение Павана, возможно, еще хуже . fopen пары с fclose и open (или creat) пары с близкими; разница не только между указателями файлов и файловыми дескрипторами, но и между совершенно разными абстракциями/API (один из которых может быть реализован через другой). – Jim Balter 19 июн. 12 2012-06-19 11:12:34

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

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

Закрытие файла имеет следующие последствия:

1) Дескриптор файла освобожден.
2) Любые блокировки записи, принадлежащие процессу в файле, разблокируются.
3) Когда все дескрипторы файлов, связанные с каналом или FIFO, были закрыты, любые непрочитанные данные отбрасываются.

Создан 19 июн. 12 2012-06-19 06:31:37 verisimilitude

+1 Замечательно, это единственный ответ здесь, который не ошибочно утверждает, что close() сбрасывает данные. – Jim Balter 19 июн. 12 2012-06-19 11:14:03

  • При записи в файл вы пишете первый в буфер, некоторые вызова функции флеша и данные записываются на файл, но других просто написать в буфер. Когда буфер заполнен, он сбрасывает в файл без прямого вызова флеша. Вы также можете использовать , если хотите, если хотите.
  • И после того, как вы его закрыли, вы больше не можете использовать дескриптор файла.

Создан 19 июн. 12 2012-06-19 07:32:37 Mark

Close закрыть файл

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

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

Сообщение добрый день, скажите как закрыть ексель (полностью выйти) с сохранением под таким же названием и без предупреждения
скажите что в этом коде не так((((

KSV Дата: Суббота, 21.03.2015, 14:29 | Сообщение № 2

200?’200px’:»+(this.scrollHeight+5)+’px’);»> ‘ подавляет предупреждения Excel
Workbooks.Application.DisplayAlerts = False

‘ сохраняет книгу в файл С ДРУГИМ именем
Excel.ActiveWorkbook.SaveAs («rl.xlsm»)

‘ сохраняет книгу в файл С ТЕМ ЖЕ именем
Excel.ActiveWorkbook.Save

‘ закрывает книгу
Workbooks.Close

‘ закрыть с сохранением (без запроса подтверждения пользователя, даже если .DisplayAlerts = True)
Workbooks.Close True

‘ закрыть без сохранения (без запроса подтверждения пользователя, даже если .DisplayAlerts = True)
Workbooks.Close False


‘ закрыть Excel (закроется только если в этом же Application больше нет открытых и не сохраненных книг,
‘ иначе будет запрашивать подтверждения сохранения, при .DisplayAlerts = True)
Application.Quit

200?’200px’:»+(this.scrollHeight+5)+’px’);»> ‘ подавляет предупреждения Excel
Workbooks.Application.DisplayAlerts = False

‘ сохраняет книгу в файл С ДРУГИМ именем
Excel.ActiveWorkbook.SaveAs («rl.xlsm»)

‘ сохраняет книгу в файл С ТЕМ ЖЕ именем
Excel.ActiveWorkbook.Save

‘ закрывает книгу
Workbooks.Close

‘ закрыть с сохранением (без запроса подтверждения пользователя, даже если .DisplayAlerts = True)
Workbooks.Close True

‘ закрыть без сохранения (без запроса подтверждения пользователя, даже если .DisplayAlerts = True)
Workbooks.Close False

‘ закрыть Excel (закроется только если в этом же Application больше нет открытых и не сохраненных книг,
‘ иначе будет запрашивать подтверждения сохранения, при .DisplayAlerts = True)
Application.Quit

Сообщение все правильно

200?’200px’:»+(this.scrollHeight+5)+’px’);»> ‘ подавляет предупреждения Excel
Workbooks.Application.DisplayAlerts = False

‘ сохраняет книгу в файл С ДРУГИМ именем
Excel.ActiveWorkbook.SaveAs («rl.xlsm»)

‘ сохраняет книгу в файл С ТЕМ ЖЕ именем
Excel.ActiveWorkbook.Save

‘ закрывает книгу
Workbooks.Close

‘ закрыть с сохранением (без запроса подтверждения пользователя, даже если .DisplayAlerts = True)
Workbooks.Close True

‘ закрыть без сохранения (без запроса подтверждения пользователя, даже если .DisplayAlerts = True)
Workbooks.Close False

‘ закрыть Excel (закроется только если в этом же Application больше нет открытых и не сохраненных книг,
‘ иначе будет запрашивать подтверждения сохранения, при .DisplayAlerts = True)
Application.Quit

85Muslim85 Дата: Суббота, 21.03.2015, 14:35 | Сообщение № 3

все отлично)) спасибки. вот чего я хотел)

Workbooks.Application.DisplayAlerts = False
Excel.ActiveWorkbook.Save
Application.Quit

все отлично)) спасибки. вот чего я хотел)

Workbooks.Application.DisplayAlerts = False
Excel.ActiveWorkbook.Save
Application.Quit 85Muslim85

Сообщение все отлично)) спасибки. вот чего я хотел)

Зачем использовать close() для закрытия файла?

Я изучаю некоторые функции файлов и, следовательно, сомневаюсь.

Мне интересно, что вам нужно позвонить close() , чтобы закрыть файл? Если я не позвонил close() после прочтения/записи файла, что может случиться? И если я позвоню close() , могу ли я использовать дескриптор файла?

Создан 19 июн. 12 2012-06-19 06:24:39 Shen

Куча ответов ниже говорит, что close() сбрасывает буферы на диск. Однако close() является функцией POSIX, и это не относится к POSIX close(). Он только освобождает блокировки и освобождает ресурсы. – Jim Balter 19 июн. 12 2012-06-19 10:51:20

6 ответов


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

Если ОС имеет ограниченные ресурсы (например, количество открытых файлов), то, не закрывая файлы, вы тратите ресурсы системы.

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

Создан 19 июн. 12 2012-06-19 06:27:51 John3136

Несколько ответов здесь утверждают, что буферы очищаются при закрытии(), но на самом деле это неверно . POSIX close() не смывает и не имеет никакого отношения к тому, записаны ли данные на устройство или когда они записаны. – Jim Balter 19 июн. 12 2012-06-19 11:04:20

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

И никогда не используйте дескриптор уже закрытого файла. Это не имеет смысла.

Создан 19 июн. 12 2012-06-19 06:26:46 Maksym Polshcha

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

Создан 19 июн. 12 2012-06-19 06:27:51 Manik Sidana

write() копирует данные из пользовательского пространства в системные буферы. Буферы системы будут очищены при удобстве системы или при синхронизации(). close() имеет * отсутствие подшипника * при промывке буферов. Он только освобождает блокировки файлов и освобождает ресурсы. – Jim Balter 19 июн. 12 2012-06-19 11:16:25

Закрытие файла: Когда это делается с файлом, его необходимо закрыть с помощью функции fclose().

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

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

(Буфер действительно только 1-мерным, несмотря на этот рисунок.)

Когда буфер заполняется (или когда файл закрыт), данные, наконец, записываются на диск.

Создан 19 июн. 12 2012-06-19 06:29:26 Hrishikesh

Небольшие исправления. Ваш ответ _seems_, чтобы указать, что файлы должны быть закрыты только с помощью ‘fclose’. Вы также можете закрыть файлы с помощью ‘close’. Его просто, что ‘fclose’ принимает указатель файла, а’ close’ принимает дескриптор файла. Кроме того, многие реализации стирают буфер, когда они сталкиваются с символом новой строки ‘\ n’ – Pavan Manjunath 19 июн. 12 2012-06-19 06:38:44

Спасибо за исправления. :)Hrishikesh 19 июн. 12 2012-06-19 06:41:41

Вопрос о close(), а не fclose(). Ничто из того, что вы написали здесь, на самом деле верно для close(). И утверждение Павана, возможно, еще хуже . fopen пары с fclose и open (или creat) пары с близкими; разница не только между указателями файлов и файловыми дескрипторами, но и между совершенно разными абстракциями/API (один из которых может быть реализован через другой). – Jim Balter 19 июн. 12 2012-06-19 11:12:34

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

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

Закрытие файла имеет следующие последствия:

1) Дескриптор файла освобожден.
2) Любые блокировки записи, принадлежащие процессу в файле, разблокируются.
3) Когда все дескрипторы файлов, связанные с каналом или FIFO, были закрыты, любые непрочитанные данные отбрасываются.

Создан 19 июн. 12 2012-06-19 06:31:37 verisimilitude

+1 Замечательно, это единственный ответ здесь, который не ошибочно утверждает, что close() сбрасывает данные. – Jim Balter 19 июн. 12 2012-06-19 11:14:03

  • При записи в файл вы пишете первый в буфер, некоторые вызова функции флеша и данные записываются на файл, но других просто написать в буфер. Когда буфер заполнен, он сбрасывает в файл без прямого вызова флеша. Вы также можете использовать , если хотите, если хотите.

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

Создан 19 июн. 12 2012-06-19 07:32:37 Mark

Как закрыть файл?

Я чувствовал себя в мире с Posix после многих лет опыта.

Потом я прочитал это сообщение от Линуса Торвальдса, около 2002:

(Б) не текущая практика

«Не портативная» часть исходит из того , что (как кто — то указывало), резьбовая среда , в которой ядро делает закрыть FD на ошибках, то FD может быть законным образом повторно использовать (ядро) для некоторых другого потока и закрытие ФД второй раз является BUG.

Не только не зацикливается до EBADF непереносимым, но любой цикл, из — за состояния гонки , что я , вероятно , заметили бы , если бы я не был «помирились», принимая такие вещи , как само собой разумеющееся.

Однако, в стандартной реализации библиотеки ССАГПЗ C ++, basic_file_stdio.cc мы имеем

Основная цель для этой библиотеки Linux, но это, кажется, не обращая внимания на Лайнуса.

Насколько я пришел к пониманию, EINTR происходит только после системного вызова блоков , что означает , что ядро получило запрос , чтобы освободить дескриптор перед началом любой работы был прерван. Таким образом , нет никакой необходимости в цикле. Действительно, SA_RESTART поведение сигнала не применяется к close и генерировать такой цикл по умолчанию, именно потому , что это небезопасно.

Это стандартная библиотека ошибка, то, верно? На каждый файл всегда закрыт приложением C ++.

EDIT: Для того, чтобы не вызывать слишком много тревоги , прежде чем некоторые гуру приходит вместе с ответом, я должен отметить , что close только кажется , чтобы иметь возможность блокировать при определенных обстоятельствах, возможно , ни один из которых никогда не применяются к обычным файлам. Я не ясно , на всех деталях, но вы не должны видеть EINTR из , close не сделав выбор в чем — то на fcntl или setsockopt . Тем не менее, возможность делает общий код библиотеки более опасным.

Что касается POSIX, R .. «s ответа на соответствующий вопрос очень четко и кратко: close() не является перезапускаемым особым случаем, и никакого цикла не должен использоваться.

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

Это не совсем ответ. Рассмотрим это больше похоже на мнение товарища программиста, в том числе обоснование этого мнения.

POSIX.1-2001 и POSIX.1-2008 описывают три возможных значения ERRNO , которые могут возникнуть: EBADF , EINTR и EIO . Состояние дескриптора после EINTR и EIO является «неопределенным» , что означает , что он может или не может быть закрыто. EBADF указывает fd не является правильным дескриптором. Другими словами, POSIX.1 явно рекомендует использовать

без каких-либо повторов цикла для закрытия дескрипторов файлов.

(Даже Austin Group дефекта # 519 R .. упомянутые, не поможет с восстановлением от close() ошибок: он оставляет неопределенный, возможен ли любой I / O после EINTR ошибки, даже если сам дескриптор остается открытым.)

Для Linux, то close() системный вызов определяются в фс / open.c , с __do_close() в фс / file.c управления блокировкой таблицы дескрипторов, и filp_close() обратно в фс / open.c заботясь о деталях.

Таким образом, запись дескриптора удаляется из таблицы безоговорочно первым , а затем в файловой системе конкретной смыва ( f_op->flush() ), с последующим уведомлением (dnotify / fsnotify крюк), и , наконец , путем удаления записи или блокировки файлов. (Большинство местных файловых систем как ext2, ext3, ext4, XFS, BFS, TMPFS, и так далее, не имеют ->flush() , поэтому данные действительный дескриптор, close() не может потерпеть неудачу. Только ecryptfs, EXOFS, предохранитель, CIFS и NFS есть ->flush() обработчики в Linux так 3.13.6, насколько я могу сказать.)

Это означает , что в Linux, если возникает ошибка записи в файловой системе конкретного ->flush() обработчика во время close() , нет никакого способа , чтобы повторить ; дескриптор файла всегда закрыт, так же , как сказал Торвальдс.

FreeBSD close() страница людей описывает точно такое же поведение.

Ни OpenBSD , ни Mac OS X close() страницы человека описывают , является ли дескриптор закрывается в случае ошибки, но я считаю , что они разделяют поведение FreeBSD.

Кажется , мне ясно , что ни одна петля не требуется или не требуется , чтобы закрыть дескриптор файла безопасно. Тем не менее, close() все еще может вернуть ошибку.

errno == EBADF указывает на дескриптор файла был уже закрыт. Если мой код встречает это неожиданно для меня это означает, есть существенная ошибка в логике коды, и этот процесс должен корректно выйти; Я предпочел бы мои процессы умереть, чем производят мусор.

Любые другие errno значения указывают на ошибку в завершении состояния файла. В Linux, это, безусловно , ошибка , связанная с промывкой оставшихся данных фактического хранения. В частности, я могу себе представить , ENOMEM в случае , если нет места для буферизации данных, EIO если эти данные не могут быть отправлены или записать фактическое устройство или носитель, EPIPE если подключение к хранилищу было потерянно, ENOSPC если хранилище уже заполнено, без оговорки к промываться данных, и так далее. Если это файл журнала, я должен был бы отчет об процесса неудачи и выйти грациозно. Если содержимое файла все еще доступны в памяти, я бы удалить (разъединить) весь файл, и повторите попытку. В противном случае я бы сообщить отказ пользователю.

(Помните, что в Linux и FreeBSD, вы не «утечки» файловых дескрипторов в случае ошибки, они гарантированно будут закрыты, даже если произошла ошибка я предполагаю, что все другие операционные системы, я мог бы использовать себя точно так же.).

Вспомогательная функция, я буду использовать теперь будет что-то вроде

Я знаю , что выше безопасен на Linux и FreeBSD, и я предполагаю , что это безопасно на всех других POSIX-систем у. Если я встречаю одно , что это не так , я могу просто заменить выше с пользовательской версией, обернув его в подходящем #ifdef для этой ОС. Причина этого сохраняет errno неизменным просто причуда моего стиля кодирования; это делает путь коротких замыкания ошибок короткий (меньше повторяющийся код).

Если я закрываю файл , который содержит важную информацию о пользователе, я сделаю fsync() ИЛИ fdatasync() на него до закрытия. Это гарантирует , что данные попадает в хранилище, но и вызывает задержку по сравнению с нормальной эксплуатации; Поэтому я не буду делать это для обычных файлов данных.

Если не будет unlink() ИНГ закрытый файл, я буду проверять closefd() возвращаемое значение, и действовать соответствующим образом . Если я могу легко повторить, я буду, но не более одного раза или два раза. Для лог — файлов и сгенерированных / потоковые файлы, я только предупредить пользователя.

Я хочу напомнить , читающий это далеко , что мы не можем сделать что — то вполне надежны ; это просто не возможно. Что мы можем сделать, и , по моему мнению , должны сделать, чтобы обнаружить , когда происходит ошибка, так же надежно , как мы можем. Если мы можем легко и с пренебрежимо использования ресурсов повторить попытку, мы должны. Во всех случаях, мы должны убедиться , что уведомление (об ошибке) распространяются на фактический человек — пользователь. Пусть человеческое беспокойство о, возможно , сложные, нуждается ли некоторые другие действия , которые необходимо сделать , прежде чем операция повторена. В конце концов, много инструментов , которые используются только как часть более крупной задачи, и лучший курс действий , как правило , зависит от того, что более крупной задачи.

Илон Маск рекомендует:  Установка под unixhp ux
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL