Текущий архив: 2004.05.16;
Скачать: CL | DM;
ВнизКакой-то странный глюк при работе с тхт файлом Найти похожие ветки
← →
AndrewVolkov (2004-05-02 16:21) [0]Может кто сталкивался.
Не могу понять в чем дело. Дело в следующем :...
procedure..
...
AssignFile(FileRecord, rPath);
Append(FileRecord);
...
procedure...
...
writeln(FileRecord, Text);
...
Суть в следующем. Есть несклько обработчиков событий при возникновении которых они просто должну построчно в конец файла добавить различную инфу - Типа журнального файла. Проблема заключается в следующем. Сработал 1-ый обработчик - добавляем строчку, далее 2-ой - опять добавляем строчку - теперь смотрим в файл - там пусто. Ок, ладно - срабатывает 3-ий - смотрим в файл - появились первые 2 строки и 3 -ья - но она почему-то обрезана. В чем может быть проблема? почему система их держит в каком-то буфере? Я пока это смог решить только сл. образом - после каждого добавления делаю СлосФайл и потом опять открываю на Аппенд.
← →
Palladin © (2004-05-02 16:25) [1]а почему система не должна держать данные в каком то буффере? особенно если borland об этом чесно предупреждает
Flush + F1
довольно таки подробно все описано
← →
Goida © (2004-05-02 16:27) [2]1. Какой тип файловой переменной?
2. Какой тип переменной Text? Это String или другой?
3. Дай больше информации.
← →
DVM © (2004-05-02 16:36) [3]
> Я пока это смог решить только сл. образом - после каждого
> добавления делаю СлосФайл и потом опять открываю на Аппенд.
А кто сказал, что это неправильно? Так надежнее.
← →
Anatoly Podgoretsky © (2004-05-02 17:00) [4]Во первых где закрытие файла, что то не наблдается, а это обязательное условия что бы чтото могло работать в многозадочной или управляемой собыиями системы. Русурс должен заниматься только на короткое время. Потом буферы, ни кто не обещал мгновенной записи, гарантировали только саму запись.
← →
AndrewVolkov (2004-05-02 17:16) [5]Так получается - каждый раз для записи надо открыть файл - сделать запись - закрыть файл?
А это не напряжно для системы - открывать, закрывать - если идет большой поток инфы для записи?
← →
Anatoly Podgoretsky © (2004-05-02 17:19) [6]AndrewVolkov (02.05.04 17:16) [5]
Не обязательно, но рекомендуется ведущими собаководами. Ну если хочешь меньше проблем. Мы же точно твоей задачи не знаем, ты даже не удосужился привести достаточный объем кода с объяснениями.
← →
panov © (2004-05-02 17:19) [7]>AndrewVolkov (02.05.04 17:16) [5]
А что, после того, как программа закончится, файл будет закрыт, в нем некорректная информация остаётся?
← →
AndrewVolkov (2004-05-02 17:26) [8]Да Простое приложение на Сокетах.Просто хочу вести логи - что, куда и зачем.
Файл : TextFile;
запись идет writeln;
то Panov
да, если не используешь Flush (за Flush спасибо Palladin - не знал такой процедуры) и перед закрытием программы делаешь CloseFile(). Пролграмма недописывает последнюю строку или несколько последних из добавляемых строк и соответственно не добавляет перевод каретки на след. строку - поэтому следующие добавления начинаются с конца последней строки
← →
panov © (2004-05-02 17:32) [9]>AndrewVolkov (02.05.04 17:26) [8]
Flush - совершенно необязательная процедура. Flush всего лишь говорит сестеме, что необходимо немедленно сбросить заполненные для записи в файл буферы на диск. Если выполнять после каждой операции записи - значительно снизит скорость работы с файлом.
У тебя, скорее всего, некорретно идет работиа с файлом.
← →
Anatoly Podgoretsky © (2004-05-02 17:32) [10]Чтото здесь не то, writeln всегда добавляет конец строки и данные никогда не теряются, у тебя явно что то не то в программе, наверно многопоточная.
← →
Palladin © (2004-05-02 17:35) [11]запись в файл должна быть потокобезопасной в случае многопоточности
никто и не утверждает что flush обязательная к применению
← →
DVM © (2004-05-02 17:48) [12]
> AndrewVolkov
Приведи полный код процедуры, пишущей в файл.
Очень вероятно, что там ошибка.
← →
AndrewVolkov (2004-05-02 17:50) [13]Да ничего у меня многопоточного нету.
..
FileRecord :TextFile;
..
procedure TfmRClient.SrSocketClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
WriteFileInfo("Client from :"+Socket.RemoteAddress+" connected");
end;
procedure TfmRClient.SrSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
WriteFileInfo("Message received from client");
end;
...
... (находится в подключаемом модуле)
procedure WriteFileInfo(sInfo:String);//этой процедуркой я получаю время и добавляю в файл передаваемую строку со временем
var
Present: TDateTime;
Hour, Minute, Second, Msecond: Word;
Str:String;
begin
Present:= Now;
DecodeTime(Present, Hour, Minute, Second, MSecond);
Str:=AddZero(IntToStr(Hour))+":"+AddZero(IntToStr(Minute))+":"+AddZero(IntToStr(Second));
SaveFileInit(GetFileName);
WriteLn(FileRecord, Str+"->",sInfo);
end;
procedure SaveFileInit(rPath:String);//"этой процедуркой я получаю путь к файлу
begin
if OpenedFile=False then begin
AssignFile(FileRecord, rPath);
if not DirectoryExists(GetCurrentDir+"\temp\") then
if not CreateDir(GetCurrentDir+"\temp\") then
raise Exception.Create("Cannot create "+GetCurrentDir+"\temp\");
case FileExists(rPath) of
True: begin
Append(FileRecord);
end;
False: begin
Rewrite(FileRecord);
end;
end;//case
OpenedFile:=True;
OpenedFileName:=rPath;
end//if
else begin//это если вдруг кто-то поменяет время при работающей проге, так как автоматом создается имя файла ддммгггг.тхт
if GetFileName<>OpenedFileName then begin
CloseFile(FileRecord);
AssignFile(FileRecord, rPath);
if not DirectoryExists(GetCurrentDir+"\temp\") then
if not CreateDir(GetCurrentDir+"\temp\") then
raise Exception.Create("Cannot create "+GetCurrentDir+"\temp\");
case FileExists(rPath) of
True: begin
Append(FileRecord);
end;
False: begin
Rewrite(FileRecord);
end;
end;//case
OpenedFile:=True;
OpenedFileName:=rPath;
end;
end;
end;
← →
AndrewVolkov (2004-05-03 00:37) [14]И где тут ошибка???
Все стандартно, без каких-либо отклонений
← →
DVM © (2004-05-03 01:20) [15]
> AndrewVolkov (03.05.04 00:37) [14]
Смотрел, я смотрел... ничего тоже такого не вижу, что могло бы привести к тому, что описано выше. Может проблема в другом месте. Попробуй писать лог файл моим кодом. Он на апи правда, но это не важно.
function PrintLog(const LogFile, LogMessage: PChar): integer;
var
hLogFile: HFILE;
NumberOfBytes: Cardinal;
dwPointer: DWord;
s: PChar;
l: integer;
begin
result := 0;
hLogFile := CreateFile(PChar(LogFile), GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if hLogFile <> INVALID_HANDLE_VALUE then
begin
dwPointer := SetFilePointer(hLogFile, 0, nil, FILE_END);
if dwPointer <> $FFFFFFFF then
begin
l := lstrlen(LogFile)+
lstrlen(LogMessage)+
lstrlen(pchar(GetDate))+
lstrlen(pchar(GetTime))+
lstrlen(pchar(", "))+
lstrlen(pchar(" - "))+
lstrlen(pchar(#13#10));
GetMem(s, l*SizeOf(Char));
lstrcat(s, pchar(GetDate));
lstrcat(s, pchar(", "));
lstrcat(s, pchar(GetTime));
lstrcat(s, pchar(" - "));
lstrcat(s, LogMessage);
lstrcat(s, pchar(#13#10));
WriteFile(hLogFile, s^, lstrlen(s) * SizeOf(Char), NumberOfBytes, nil);
if NumberOfBytes = Cardinal(lstrlen(s) * SizeOf(Char)) then result := 1;
FreeMem(s);
end;
CloseHandle(hLogFile);
end;
//if Result = 0 then MessageBox(0, "Log File Error!", "Error!", MB_OK or MB_ICONERROR or MB_SETFOREGROUND or MB_TOPMOST);
end;
← →
AndrewVolkov (2004-05-03 10:20) [16]Не было времени разобраться, нужно было лететь,
но кодlstrlen(pchar(GetDate))+
lstrlen(pchar(GetTime))+
у меня не пошел - ругается что нет такого.
Хотя в SysUtils - есть -только GetDate процедура - как она может чего-то вернуть?
← →
DVM © (2004-05-03 12:11) [17]
> AndrewVolkov (03.05.04 10:20) [16]
Да выкинь ты ее. Это другая функция, моя собственная. Дату и время возвращает. Я sysutils не использовал.
← →
AndrewVolkov (2004-05-03 20:18) [18]Тады понял. Сенкс
← →
Galera © (2004-05-04 15:46) [19]а критические секции ничем тебе не помогут?
← →
DVM © (2004-05-04 15:54) [20]
> а критические секции ничем тебе не помогут?
так он говорит, что нету многопоточности.
← →
Erik © (2004-05-04 16:54) [21]Можно взять из инета логер и спокойно писать. Если неохота, то можеш использовать мой код:
procedure TRealEvent.Close;
begin
FileActive := False;
{$I-}
Flush(F);
CloseFile(F);
{$I+}
end;
procedure TRealEvent.Log;
Var Buf: String;
Const LogFile = "C:\UDPLog.txt";
begin
Buf := Format("%d;%d;%d;%d;",[DecNoToInt(Params.Decoder),Params.Cmd,
fConf.Code, fConf.Content]);
if not FileActive then begin
AssignFile(F,LogFile);
{$I-}
Reset(F);
{$I+}
IOResult;
if Not FileExists(LogFile) then
Rewrite(F);
FileActive := True;
end;
Append(F);
Writeln(F,Buf);
end;
Все это примерно в таком треде крутилось:
procedure TRealEvent.Execute;
Var Status: DWord;
Label Retry;
begin
Retry:
Status := WaitForMultipleObjects(Ord(High(tmEvent.Event))+1, @tmEvent.Event , false, 5000);
// if FActive and (TActivEvent(Status)<>actExit) then exit;
FActive := True;
Case TActivEvent(Status) of
actExit: Terminate;
actCmd: Log;
else
if Status = WAIT_TIMEOUT then Close;
end;
FActive := False;
if not Terminated then Goto Retry
else Close;
end;
← →
Alex Konshin © (2004-05-04 19:37) [22]При многопоточном выводе в файл нужно писать напрямую используя функции WriteFile (вроде не наврал).
Страницы: 1 вся ветка
Текущий архив: 2004.05.16;
Скачать: CL | DM;
Память: 0.51 MB
Время: 0.094 c