Меню

Ошибка доступа к файлу делфи

    Процесс не может получить доступ к файлу, так как этот файл занят другим процессом… Но это не точно… Как показала практика, для программы на Delphi это действительно не точно.
    При открытии файла в режиме «только для чтения» в параметре определяющем режим доступа к файлу обычно передают комбинацию «fmOpenRead or fmShareDenyNone». Но оказалось, что это избавляет только от части ошибок «Процесс не может получить доступ к файлу, так как этот файл занят другим процессом» или «The process cannot access the file because it is being used by another process».
    Для начала немного теории. В Delphi режим доступа к файлу, определяется комбинацией константы режима открытия файла (fmOpen*) и константы разделения доступа к файлу (fmShare*). Эти константы описанны в модуле System.SysUtils. Приведу их значение для ОС Windows:

Наименование Значение Описание
Режимы открытия файла
fmOpenRead $0000 Открытие файла только для чтения
fmOpenWrite $0001 Открытие файла только для записи
fmOpenReadWrite $0002 Открытие файла для чтения и записи
Режимы разделения доступа
fmShareExclusive $0010 Другие приложения не имеют доступа к файлу
fmShareDenyWrite $0020 Другие приложения могут только читать файл
fmShareDenyRead $0030 Другие приложения могут только писать в файл
fmShareDenyNone $0040 Другие приложения могут читать файл и писать в него

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

Вариант 1. Откроем файлы без указания режима разделения доступа

try
  with TFileStream.Create(sFileName, fmOpenRead) do
    try
      // читаем секретные материалы
    finally
      Free
    end;
except
  on E: Exception do
    Writeln(E.Message);
end;

У меня в каталоге для хранения временных файлов нашлось 23 файла, которые заняты какими-то процессами.

Вариант 2. Откроем файлы в режиме разделения доступа «fmShareDenyNone»

try
  with TFileStream.Create(sFileName, fmOpenRead or fmShareDenyNone) do
    try
      // истина где-то рядом
    finally
      Free
    end;
except
  on E: Exception do
    Writeln(E.Message);
end;

Теперь получаем 16 файлов занятых другими процессами и радуемся улучшению результата. Радуемся, но не долго. Некоторые из этих «занятых» файлов открываются на просмотр в «Lister» из Total Commander! Как так?!?

Метод TFileStream.Create приводит к функции FileOpen из System.SysUtils:

function FileOpen(const FileName: string; Mode: LongWord): THandle;
const
  AccessMode: array[0..2] of LongWord = (
    GENERIC_READ,
    GENERIC_WRITE,
    GENERIC_READ or GENERIC_WRITE);
  ShareMode: array[0..4] of LongWord = (
    0,
    0,
    FILE_SHARE_READ,
    FILE_SHARE_WRITE,
    FILE_SHARE_READ or FILE_SHARE_WRITE);
begin
  Result := INVALID_HANDLE_VALUE;
  if ((Mode and 3) <= fmOpenReadWrite) and
    ((Mode and $F0) <= fmShareDenyNone) then
    Result := CreateFile(PChar(FileName), AccessMode[Mode and 3],
      ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL, 0);
end;

Получается, что в режиме разделения доступа fmShareDenyNone функция CreateFile вызывается с параметром dwShareMode = FILE_SHARE_READ or FILE_SHARE_WRITE. Согласно документации от Microsoft, в WinAPI, кроме FILE_SHARE_READ и FILE_SHARE_WRITE, есть еще режим разделения доступа FILE_SHARE_DELETE. В Delphi константа FILE_SHARE_DELETE описана в модуле Winapi.Windows, но не используется.

Откроем файл для нашего потока сами с учетом FILE_SHARE_DELETE:

var
  h: THandle;
...
h := CreateFile(PChar(sFileName),
                GENERIC_READ,
                FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
                nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if h = INVALID_HANDLE_VALUE
  then Writeln(SysErrorMessage(GetLastError))
  else with TFileStream.Create(h) do
         try
           // X-файлы наши!
         finally
           Free
         end;

Оказывается, что у меня в каталоге для хранения временных файлов реально только 4 файла занятых другими процессами!

В результате я добавил себе в проект функцию

function FileOpenAsReadOnly(const sFileName: String): THandle;
begin
  Result := CreateFile(PChar(sFileName),
                       GENERIC_READ,
                       FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
                       nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if Result = INVALID_HANDLE_VALUE then
    raise EFOpenError.CreateResFmt(@SFOpenErrorEx, 
                                   [ExpandFileName(sFileName), 
                                   SysErrorMessage(GetLastError)])
end;

и использовал ее для открытия файлов в режиме «только для чтения»:

TFileStream.Create(FileOpenAsReadOnly(sFileName))

    Конечно, полностью победить эту ошибку мне не удалось, но 4 файла против 23 или 16 — это тоже хорошее достижение. Интересно, то, что разработчики из Borland потеряли FILE_SHARE_DELETE, а разработчики из Embarcadero не нашли — это ошибка в Delphi? Или так надо, и я чего-то не понимаю?


0 / 0 / 0

Регистрация: 24.07.2014

Сообщений: 9

1

17.08.2014, 13:06. Показов 19616. Ответов 11


У меня выбрасывает ошибку в Delphi… Переустановка не помогла, что делать?

Миниатюры

Delphi 2010: "Процесс не может получить доступ к файлу, так как этот файл занят другим процессом"
 

Delphi 2010: "Процесс не может получить доступ к файлу, так как этот файл занят другим процессом"
 

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

17.08.2014, 13:06

11

Эксперт Pascal/Delphi

4880 / 2753 / 848

Регистрация: 04.10.2012

Сообщений: 10,037

17.08.2014, 15:55

2

Цитата
Сообщение от SnowLotus
Посмотреть сообщение

У меня выбрасывает ошибку в Delphi

когда?



0



Пишу на Delphi…иногда

1422 / 1277 / 286

Регистрация: 03.12.2012

Сообщений: 3,914

Записей в блоге: 5

17.08.2014, 16:38

3

запускайте Delphi от имени администратора



0



0 / 0 / 0

Регистрация: 24.07.2014

Сообщений: 9

17.08.2014, 20:32

 [ТС]

4

не помогло

Добавлено через 22 секунды
Ошибка при запуске…



0



Эксперт Pascal/Delphi

4880 / 2753 / 848

Регистрация: 04.10.2012

Сообщений: 10,037

17.08.2014, 20:53

5

Цитата
Сообщение от SnowLotus
Посмотреть сообщение

Ошибка при запуске

эта проблема связана с ОС, а не со средой, точнее с обновлениями. В Delphi 2007-2010 эти обновления блокируют доступ к файлу «EditorLineEnds.ttr».
1. Удалите обновления KB2982791, KB2970228,
2 .Перезагрузите машину,
3. Загрузитесь в Save Mode и удалите этот файл.



1



0 / 0 / 0

Регистрация: 24.07.2014

Сообщений: 9

17.08.2014, 21:16

 [ТС]

6

Удалите обновления KB2982791, KB2970228, Как??? Что это??? (простите ламера)



0



2 / 2 / 0

Регистрация: 05.08.2013

Сообщений: 24

17.08.2014, 21:44

7

Удалите обновления KB2982791, KB2970228, Как??? Что это??? (простите ламера)

Это обновления Windows. Удалить можно так -Панель управления-Центр обновления Windows- установленные обновления.



1



Эксперт Pascal/Delphi

4880 / 2753 / 848

Регистрация: 04.10.2012

Сообщений: 10,037

17.08.2014, 21:46

8

Цитата
Сообщение от SnowLotus
Посмотреть сообщение

Как??? Что это???

Так



2



1 / 1 / 0

Регистрация: 14.07.2014

Сообщений: 31

16.10.2014, 10:16

9

эта же ошибка Delphi 2007 error: “Cannot create file C:Users%Username%AppDataLocalTempEditorLineE nds.ttr” возникла у меня на win8.1×64
решил я ее прочитав вот это: http://www.danielmagin.de/blog… 2007-2010/ — иностранный ресурс, возможно вам потребуется переводчик
и установив вот этот фикс: http://andy.jgknet.de/blog/ide-tools/ide-fix-pack/ — иностранный ресурс, возможно вам потребуется переводчик



1



Galiahmetov

19.10.2014, 16:06

10

Можно решить эту проблему через запуск Delphi 2010
через следующий пакетный файл:

Windows Batch file
1
2
3
4
5
@echo off
cd C:UsersUSERNAMEAppDataLocalTemp
del EditorLineEnds.tt*
ren EditorLineEnds.ttr EditorLineEnds.tt%time:~3,2%%time:~6,2%
start /D "C:Program FilesEmbarcaderoRAD Studio7.0bin" bds.exe

Здесь USERNAME замените на свой.
Windows не позволяет удалить файл EditorLineEnds.ttr,
но разрешает его переименовать. При очередном запуске Delphi
этот файл будет переименован в EditorLineEnds.ttMMCC,
MMCC — это минуты и секунды текущего времени.
То есть появится новый файл, например EditorLineEnds.tt2058.
При каждом новом запуске Delphi будет появляться новый файл
EditorLineEnds.ttMMCC, а также файл EditorLineEnds.ttr, при этом
Windows не позволит удалить ни один из них. Конечно таких
файлов EditorLineEnds.ttMMCC может накопиться много (равно
количеству запусков Delphi), но после перезагрузки Windows
все файлы EditorLineEnds.ttMMCC будут свободны и можно
будет их удалить ( 3-я строка пакетного файла: del EditorLineEnds.tt*).

6 / 6 / 0

Регистрация: 21.07.2012

Сообщений: 144

09.03.2016, 16:56

11

Для решения проблемы в IDE Dephi 2010 нужно скачать это расширение по этой ссылке.
http://andy.jgknet.de/blog/ide-tools/ide-fix-pack/
IDE Fix Pack 5.94 (unsupported). У меня теперь работает отлично и ничего не вылезает, никаких окон.



0



2 / 2 / 0

Регистрация: 02.07.2018

Сообщений: 10

06.02.2019, 15:08

12

murfik не помогло. Замучала эта ошибка. Еще и глюк приключился — расширило все мои компоненты и размер шрифтов.
Панели вверху вообще перемешало.



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

06.02.2019, 15:08

Помогаю со студенческими работами здесь

Ошибка: «Процесс не может получить доступ к файлу, так как этот файл используется другим процессом»
Здравствуйте! Я написал код кнопки сохранитьToolStripMenuItem, у меня в коде вылезает ошибка:…

Процесс не может получить доступ к файлу «C:ProSettingNameFunction.txt», так как этот файл используется другим процессом
Помогите, пожалуйста, не могу понять в чем причина.
using System;
using…

IO Exception «Процесс не может получить доступ к файлу, т.к. этот файл используется другим процессом»
Здравствуйте, есть код

private void t_Tick(object sender, EventArgs e)
{

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

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

12

    msm.ru

    Нравится ресурс?

    Помоги проекту!

    Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.


    Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
    1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
    2. Как «свернуть» программу в трей.
    3. Как «скрыться» от Ctrl + Alt + Del (заблокировать их и т.п.)
    4. Как прочитать список файлов, поддиректорий в директории?
    5. Как запустить программу/файл?
    … (продолжение следует) …


    Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
    Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


    Внимание
    Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
    Повторная попытка — 60 дней. Последующие попытки бан.
    Мат в разделе — бан на три месяца…

    >
    ошибка доступа к файлу
    , или как закрыть файл принудительно?

    • Подписаться на тему
    • Сообщить другу
    • Скачать/распечатать тему



    Сообщ.
    #1

    ,
    27.01.08, 02:08

      Junior

      *

      Рейтинг (т): 1

      Пытаюсь сохранить значение TStringList в файл с помощью TStringlist.SaveToFile()

      Но иногда вылетает ошибка доступа к файлу — пишет что файл уже открыт другим процессом. Т.е. иногда все работает, а иногда нет :(

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

      P.S. С этим файлом я работаю только через TStringList.SaveToFile() и TWebBrowser.Navigate().

      Master

      ViktorXP



      Сообщ.
      #2

      ,
      27.01.08, 06:43

        ExpandedWrap disabled

          try

             MyStringlist.SaveToFile(‘кудато в небытие’);

          except

             ShowMessage(‘Закрой файл, а то глаз выколю!!’);

             // тут можна сказать левой процедуре чобы та закрыла свой доступ и дала дорогу молодым)))

             // а потом вызвать процедуру повтора

          end;

        Добавлено 27.01.08, 06:45
        просто закрыть файл не зная хендл трудновато будет)))


        tyoma_first



        Сообщ.
        #3

        ,
        27.01.08, 12:28

          Junior

          *

          Рейтинг (т): 1

          :whistle: Я именно так и делаю. Меня как раз интересует момент

          ExpandedWrap disabled

            // тут можна сказать левой процедуре чобы та закрыла свой доступ и дала дорогу молодым)))

            // а потом вызвать процедуру повтора

          Какую процедуру использовать или как написать свою?

          Напомню что я с этим файлом работаю только с помощью TStringList.SaveToFile() и TWebBrowser.Navigate(). Может быть TWebBrowser держит файл открытым? Если да — то как ему сказать что файлы закрывать надо?..

          Master

          ViktorXP



          Сообщ.
          #4

          ,
          27.01.08, 17:35

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

            илиже перед сохранением зделать
            WebBrowser1.Stop;
            чтобы он прекратил загружать страничку


            tyoma_first



            Сообщ.
            #5

            ,
            01.02.08, 22:27

              Junior

              *

              Рейтинг (т): 1

              Цитата ViktorXP @ 27.01.08, 17:35

              илиже перед сохранением зделать
              WebBrowser1.Stop;
              чтобы он прекратил загружать страничку

              делал — не помогает :wall:


              simsergey



              Сообщ.
              #6

              ,
              02.02.08, 09:46

                Цитата ViktorXP @ 27.01.08, 06:43

                ShowMessage(‘Закрой файл, а то глаз выколю!!’);

                Гениально! Надо себе в прогу засунуть :D

                Master

                ViktorXP



                Сообщ.
                #7

                ,
                03.02.08, 08:12

                  tyoma_first ну тада показывай весь исходник
                  походу у тебя еще чтото файл ковыряет


                  tyoma_first



                  Сообщ.
                  #8

                  ,
                  03.02.08, 19:18

                    Junior

                    *

                    Рейтинг (т): 1

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

                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

                    0 пользователей:

                    • Предыдущая тема
                    • Delphi: Общие вопросы
                    • Следующая тема

                    Рейтинг@Mail.ru

                    [ Script execution time: 0,0292 ]   [ 16 queries used ]   [ Generated: 30.01.23, 06:42 GMT ]  

                    It is not AssignFile() that fails, but your call to Rewrite() on a file with the Hidden attribute set. Following explains it:

                    Typically you call Rewrite(F) in order to erase the file and write new data to it with subsequent Write(F, ...) or WriteLn(F, ...) calls.

                    From docs (System.Rewrite):

                    If an external file with the same name already exists, it is deleted
                    and a new empty file is created in its place.

                    There is no problem opening the file for writing with the Append() command.

                    (Based on above I drew the conclusion that it is the deletion that fails with the Access denied message. That was cutting the corners too much.)


                    Beaten by comments I traced through the code and compared actual code with MSDN documentation for CreateFile:

                    Actual code:

                    // if mode is fmOutput (as it is for Rewrite)
                    OpenMode = GENERIC_WRITE
                    Flags = CREATE_ALWAYS
                    // ...
                    Temp := CreateFile(t.Name, OpenMode, FILE_SHARE_READ, nil, Flags, FILE_ATTRIBUTE_NORMAL, 0);
                    

                    And documentation:

                    If CREATE_ALWAYS and FILE_ATTRIBUTE_NORMAL are specified, CreateFile
                    fails and sets the last error to ERROR_ACCESS_DENIED if the file
                    exists and has the FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_SYSTEM
                    attribute.

                    Calling Rewrite() on a existing file with the hidden attribute fails always.

                    It is not AssignFile() that fails, but your call to Rewrite() on a file with the Hidden attribute set. Following explains it:

                    Typically you call Rewrite(F) in order to erase the file and write new data to it with subsequent Write(F, ...) or WriteLn(F, ...) calls.

                    From docs (System.Rewrite):

                    If an external file with the same name already exists, it is deleted
                    and a new empty file is created in its place.

                    There is no problem opening the file for writing with the Append() command.

                    (Based on above I drew the conclusion that it is the deletion that fails with the Access denied message. That was cutting the corners too much.)


                    Beaten by comments I traced through the code and compared actual code with MSDN documentation for CreateFile:

                    Actual code:

                    // if mode is fmOutput (as it is for Rewrite)
                    OpenMode = GENERIC_WRITE
                    Flags = CREATE_ALWAYS
                    // ...
                    Temp := CreateFile(t.Name, OpenMode, FILE_SHARE_READ, nil, Flags, FILE_ATTRIBUTE_NORMAL, 0);
                    

                    And documentation:

                    If CREATE_ALWAYS and FILE_ATTRIBUTE_NORMAL are specified, CreateFile
                    fails and sets the last error to ERROR_ACCESS_DENIED if the file
                    exists and has the FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_SYSTEM
                    attribute.

                    Calling Rewrite() on a existing file with the hidden attribute fails always.

                    0 0 голоса
                    Рейтинг статьи
                    Подписаться
                    Уведомить о
                    guest

                    0 комментариев
                    Старые
                    Новые Популярные
                    Межтекстовые Отзывы
                    Посмотреть все комментарии

                    А вот еще интересные материалы:

                  • Яшка сломя голову остановился исправьте ошибки
                  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
                  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
                  • Ошибка доступа к файлу c programdata 1c 1cv8 1cv8connn pfl
                  • Ошибка доступа к файлу c inetpub wwwroot