Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.53 MB
Время: 0.026 c
1-1083228255
Senator
2004-04-29 12:44
2004.05.16
MDI


9-1072057789
Dmitrich
2003-12-22 04:49
2004.05.16
опять DoCollision


1-1083671069
ЁПРСТ
2004-05-04 15:44
2004.05.16
Как убить компонент при выходе из него


7-1081344537
Fotog
2004-04-07 17:28
2004.05.16
CR-R


8-1077356458
Batoon
2004-02-21 12:40
2004.05.16
ПОДСКАЖИТЕ ссылочки на исходники FFT для DELPHI