Страница 1 из 1
Access denied при частом открытии файла
Добавлено: 03.11.2008 16:40:50
voltron
Есть у нас в конторе программа (написанная не мной), которая читает текстовые файлы определенного формата, извлекает из них информацию, и после форматирования пишет ее в результирующий файл. Вот фрагмент кода:
Код: Выделить всё
// просматриваем исходные файлы
for i:=0 to lstFiles.Lines.Count - 1 do
begin
//сначала считывается и обрабатывается исх. файл
lstSource.LoadFromFile(lstFiles.Lines[i]);
...
//результат обработки пишем в результирующий файл
AssignFile(OutFile, OutFileName);
try
Append(OutFile);
//запись информации
write(OutFile, CadNom + SEPARATOR);
write(OutFile, Owner + SEPARATOR);
...
writeln(OutFile, ActRegDate); //формируем переход на след. строку
CloseFile(OutFile);
except
on E:EInOutError do
DebugLn('Error: ' + E.Message);
end;
end;
При большом количестве исходных файлов (4000 и больше), ближе к концу списка начинает возникать ошибка "Access denied" на строке Append(OutFile). Файл-результат больше нигде не используется, после записи каждой порции данных закрывается. Пробовал вынести открытие и закрытие результирующего файла за пределы цикла (чтобы не открывать файл при записи новой порции данных) - не помогло.
В чем может быть проблема и как лучше организовать процесс записи (пишутся строки разной длины)?
Re: Access denied при частом открытии файла
Добавлено: 03.11.2008 16:49:16
FedeX
Попробуй использовать функцию Flush перед записью следующей порции. (я ей не пользовался, но вроде есть такая).
Попробуй писать всё в одну строку (конкатенировать или, если возможно, сразу выделить необходимый обьём), и только в конце писать всю строку в бинарный файл.
Re: Access denied при частом открытии файла
Добавлено: 03.11.2008 17:14:13
Vadim
voltronПопробуйте вообще использовать класс TStringList. У него есть метод SaveToFile(), при этом он сразу выкидывает в файл весь свой набор строк:
Код: Выделить всё
Var
st: TStringList;
Begin
st:=TStringList.Create;
// просматриваем исходные файлы
for i:=0 to lstFiles.Lines.Count - 1 do
begin
//сначала считывается и обрабатывается исх. файл
lstSource.LoadFromFile(lstFiles.Lines[i]);
...
//результат обработки пишем в StringList
//запись информации
st.Add(CadNom + SEPARATOR + Owner + SEPARATOR+...);
...
End;
st.SaveToFile(OutFileName);
st.Free;
Съэкономит кучу времени, т.к. выходной файл открывается всего один раз.
Re: Access denied при частом открытии файла
Добавлено: 03.11.2008 17:44:26
voltron
FedeX писал(а):Попробуй использовать функцию Flush перед записью следующей порции. (я ей не пользовался, но вроде есть такая).
Есть такая процедура, она выполняет принудительную запись изменений (сбрасывает файловый буфер на диск). Данные нормально пишутся и без нее, проблема возникает при попытке открыть файл на дозапись, т.е. Flush здесь не причем.
Vadim писал(а):Попробуйте вообще использовать класс TStringList
Именно так и собираюсь поступить. Просто интересует причина появления таких ошибок. Нашел на Королевстве Дельфи похожую проблему
http://www.delphikingdom.com/asp/answer.asp?IDAnswer=50614
Re: Access denied при частом открытии файла
Добавлено: 03.11.2008 18:18:26
Vadim
voltron писал(а):Просто интересует причина появления таких ошибок.
Точно сказать не могу, т.к. ни разу с таким не сталкивался, но, возможно, причина в кэшировании. Файл при следующей итерации, пытается открываться раньше, чем успевает сбросить туда данные предыдущая итерация. Отсюда и "Access denied". Впрочем, может быть и ошибаюсь.

А вообще предпочитаю не проводить множественные открытия-закрытия файлов, т.к. это сильно тормозит программу.
Re: Access denied при частом открытии файла
Добавлено: 03.11.2008 20:09:32
Logo
Здесь видимо превышает допустимое количество открытых файлов. Тоесть, в цикле идет быстрая посылка комманд (сообщений) системе, система файлы откравыет, но закрывает с запаздыванием. Если нельзя изменить алгоритм, то побробуйте вставить Application.ProcessMessage после закрытия файла, да и после открытия можно (будет еще тормознутее

).
Re: Access denied при частом открытии файла
Добавлено: 03.11.2008 20:18:11
shade
voltron писал(а):Файл-результат больше нигде не используется, после записи каждой порции данных закрывается.
Если результат больше нигде не используется, то может и не закрывать? Один раз открыл и пиши?...
Re: Access denied при частом открытии файла
Добавлено: 04.11.2008 00:45:50
Padre_Mortius
тоже столкнулся с этой проблемой. Только работу с файлом оформил через потоки. Ошибка плавающая. Повторить ее получается крайне редко (у меня).
Код: Выделить всё
Procedure WriteToLog(Const FileStr, PathStr, Code: AnsiString);
Var
LogStream: TFileStream;
ResultStr, S, LogFileName: AnsiString;
Begin
LogFileName := ExtractFilePath(ParamStr(0)) + 'Log\transport.log';
ResultStr := Code;
S := '';
Try
If Not FileExists(LogFileName) Then
LogStream := TFileStream.Create(LogFileName, fmCreate)
Else LogStream := TFileStream.Create(LogFileName, fmOpenWrite);
LogStream.Seek(0, sofromEnd);
If length(FileStr)<>0 Then ResultStr := StringReplace (Code, '%f', FileStr, [rfReplaceAll]);
If length(PathStr)<>0 Then ResultStr := StringReplace (ResultStr, '%s', PathStr, [rfReplaceAll]);
DateTimeToString(S, 'DD.MM.YYYY HH:NN:SS ', Now);
ResultStr := S + ' ' + ResultStr + #13 + #10;
LogStream.Write (PChar(ResultStr)[0], Length(ResultStr));
Finally
LogStream.Free;
End;
End;