Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.05.16;
Скачать: [xml.tar.bz2];

Вниз

Какой-то странный глюк при работе с тхт файлом   Найти похожие ветки 

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.032 c
6-1080231779
Вика
2004-03-25 19:22
2004.05.16
авторизация и клиент-сервер MIDAS


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


9-1073424736
Orcy
2004-01-07 00:32
2004.05.16
Как загрузить 3ds в OpenGL


1-1083141363
Tsvetkov A.V.
2004-04-28 12:36
2004.05.16
Потоки в ДЛЛ


9-1071409745
ZAROLF
2003-12-14 16:49
2004.05.16
Нужен совет к 2D аркаде!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский