Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Открытие занятого файла


Автор: pautina 27.1.2009, 12:06
Здравствуйте Уважаемое сообщество. Вы ни скажете каким образом можно открыть занятый файл.
У меня есть участок кода, программа позволяет считать данные из файла лога logfile.txt этот файл лога создаёт программа generator.exe текстовый файл постоянно заполняется данными.
Участок кода
Код

procedure TForm1.Button1Click(Sender: TObject);

var SourceST,DestST:TStringList;
    i:integer; handle:integer;
    s:string;
begin
 SourceST:=TStringList.Create;
 DestST:=TStringList.Create;
 if form1.OpenDialog1.Execute then SourceST.LoadFromFile(form1.OpenDialog1.FileName);

 // FileSetAttr('C:\Documents and Settings\сергей\Рабочий стол\Задание\logfile.txt', faReadOnly);  // Атрибуты для файла только чтение
 Handle := FileOpen('C:\Documents and Settings\сергей\Рабочий стол\Задание\logfile.txt', fmOpenRead );
 {$I-}



 for i:=0 to SourceST.Count-1 do
 begin

  try
    // Вывод временных меток
    if pos(':',SourceST[i])<>0 then // Если строка с : найдена
    SourceST[i]:=Copy(SourceST[i],Length(SourceST[i])-19,20)
    else
    // Вывод чисел
     if ((pos('|',SourceST[i])<>0) and ((pos('1',SourceST[i])<>0)
         or (pos('2',SourceST[i])<>0) or (pos('3',SourceST[i])<>0)
         or (pos('4',SourceST[i])<>0) or (pos('5',SourceST[i])<>0)
         or (pos('6',SourceST[i])<>0) or (pos('7',SourceST[i])<>0)
         or (pos('8',SourceST[i])<>0) or (pos('9',SourceST[i])<>0)
         or (pos('0',SourceST[i])<>0)))
     then // Если строка с разделителем | найдена и в строке есть цыфры
     SourceST[i]:=Copy(SourceST[i],Length(SourceST[i])-47,48)
    // Если ни временных меток ни чисел нет то строка пустая
    else SourceST[i]:='';
    DestST.Add(SourceST[i]);
  except
  end;

 end;
 DestST.SaveToFile('112.xls'); //   DestST.SaveToFile('112.txt'); Вывод результата
 SourceST.Free;
 DestST.Free;
end;

Как сделать чтоб программа работала, а то сейчас программа работает только когда файл logfile.txt сохранён, а мне нужно чтоб считывались нужные данные при запущенной пр. generator.exe,  как то это связано с FileStreamLog, Ни скажете как изменить код. 

Автор: Akella 27.1.2009, 12:39
Попробуй работать с Stream

Автор: pautina 27.1.2009, 12:41
Ни скажете как изменить мой код.

Автор: Данкинг 27.1.2009, 12:51
Цитата(pautina @ 27.1.2009,  12:41)
Ни скажете как изменить мой код.

Да.

По теме: а если через файловую переменную и RESET открывать?

Автор: pautina 27.1.2009, 13:34
Но участок кода у меня рабочий, только считать данные при запущенном приложении не может, как его изменить для работы со stream, может кто поможет
Код

procedure TForm1.Button1Click(Sender: TObject);

var SourceST,DestST:TStringList;
    i:integer; handle:integer;
    s:string;
begin
 SourceST:=TStringList.Create;
 DestST:=TStringList.Create;
 if form1.OpenDialog1.Execute then SourceST.LoadFromFile(form1.OpenDialog1.FileName);

 // FileSetAttr('C:\Documents and Settings\сергей\Рабочий стол\Задание\logfile.txt', faReadOnly);  // Атрибуты для файла только чтение
 Handle := FileOpen('C:\Documents and Settings\сергей\Рабочий стол\Задание\logfile.txt', fmOpenRead );
 {$I-}



 for i:=0 to SourceST.Count-1 do
 begin

  try
    // Вывод временных меток
    if pos(':',SourceST[i])<>0 then // Если строка с : найдена
    SourceST[i]:=Copy(SourceST[i],Length(SourceST[i])-19,20)
    else
    // Вывод чисел
     if ((pos('|',SourceST[i])<>0) and ((pos('1',SourceST[i])<>0)
         or (pos('2',SourceST[i])<>0) or (pos('3',SourceST[i])<>0)
         or (pos('4',SourceST[i])<>0) or (pos('5',SourceST[i])<>0)
         or (pos('6',SourceST[i])<>0) or (pos('7',SourceST[i])<>0)
         or (pos('8',SourceST[i])<>0) or (pos('9',SourceST[i])<>0)
         or (pos('0',SourceST[i])<>0)))
     then // Если строка с разделителем | найдена и в строке есть цыфры
     SourceST[i]:=Copy(SourceST[i],Length(SourceST[i])-47,48)
    // Если ни временных меток ни чисел нет то строка пустая
    else SourceST[i]:='';
    DestST.Add(SourceST[i]);
  except
  end;

 end;
 DestST.SaveToFile('112.xls'); //   DestST.SaveToFile('112.txt'); Вывод результата
 SourceST.Free;
 DestST.Free;
end; 
 

Автор: Quartz 27.1.2009, 15:18
Цитата(Akella @  27.1.2009,  12:39 Найти цитируемый пост)
Попробуй работать с Stream

Не имеет смысла, в TFileStream используются те же  FileOpen/FileCreate.

Цитата(pautina @  27.1.2009,  12:41 Найти цитируемый пост)
Ни скажете как изменить мой код.

Конечно, скажем!  smile 
Проблема в том, что Вы пытаетесь изменить способ доступа к уже открытому файлу.
Тут подойдут следующие параметры:
Код
  // 1. Программа, пишушая логи: открываем на запись, запрещая писАть остальным
  FileOpen( 'C:\logfile.txt', fmOpenWrite + fmShareDenyWrite );
  // 2. Читающая программа: открываем на чтение, ShareMode без изменений
  FileOpen( 'C:\logfile.txt', fmOpenRead + fmShareDenyNone );

ЗЫ: Все-таки лучше переписать на TStream, будет надежнее и удобнее, хотя к данной проблеме это не имеет отношения.

Автор: ZBugz 27.1.2009, 17:49
fmShareDenyNone or fmShareCompat пробывал ?

Автор: pautina 27.1.2009, 18:06
Да как только я ни пробовал.
Использовал такой код, 
содержимое logfile.txt копировал в файл Temp_logfile.txt'
Код

procedure TForm1.Button1Click(Sender: TObject);

var SourceST,DestST:TStringList;
    i:integer;
    FS1, FS2: TFileStream;
    s:string;

begin
 SourceST:=TStringList.Create;
 DestST:=TStringList.Create;
 // if form1.OpenDialog1.Execute then SourceST.LoadFromFile(form1.OpenDialog1.FileName);
 if OpenDialog1.Execute then
  begin
   // Îòêðûâàåì ôàéë òàê ÷òîáû ê íåìó ïóñòèëè
   FS1:= TFileStream.Create(OpenDialog1.FileName, fmShareDenyNone);
   // Ñîõðàíÿåì âî âðåìåííûé ôàéë
   FS2:= TFileStream.Create('C:\Temp_logfile.txt', fmOpenWrite or fmCreate);
   FS2.CopyFrom (FS1, FS1.Size);
   // Áåðåì ñîäåðæèìîå èç âðåìåííîãî ôàéëà
   SourceST.LoadFromFile('C:\Temp_logfile.txt');
   // Ìîæíî åãî óäàëèòü íàïðèìåð
   // DeleteFile('C:\Temp_logfile.txt');

 for i:=0 to SourceST.Count-1 do
 begin

  try
    // Âûâîä âðåìåííûõ ìåòîê
    if pos(':',SourceST[i])<>0 then // Åñëè ñòðîêà ñ : íàéäåíà
    SourceST[i]:=Copy(SourceST[i],Length(SourceST[i])-19,20)
    else
    // Âûâîä ÷èñåë
     if ((pos('|',SourceST[i])<>0) and ((pos('1',SourceST[i])<>0)
         or (pos('2',SourceST[i])<>0) or (pos('3',SourceST[i])<>0)
         or (pos('4',SourceST[i])<>0) or (pos('5',SourceST[i])<>0)
         or (pos('6',SourceST[i])<>0) or (pos('7',SourceST[i])<>0)
         or (pos('8',SourceST[i])<>0) or (pos('9',SourceST[i])<>0)
         or (pos('0',SourceST[i])<>0)))

     then // Åñëè ñòðîêà ñ ðàçäåëèòåëåì | íàéäåíà è â ñòðîêå åñòü öûôðû
     SourceST[i]:=Copy(SourceST[i],Length(SourceST[i])-47,48)
    // Åñëè íè âðåìåííûõ ìåòîê íè ÷èñåë íåò òî ñòðîêà ïóñòàÿ
    else SourceST[i]:='';
    DestST.Add(SourceST[i]);
  except
  end;

 end;
 DestST.SaveToFile('112.txt'); //   DestST.SaveToFile('112.xls');
 SourceST.Free;
 DestST.Free;
end;
end;

Где ошибка низнаю. Нужна помощь, delphi говорит нет доступа к файле Temp_logfile.txt'

Автор: Quartz 27.1.2009, 18:50
Цитата(pautina @  27.1.2009,  18:06 Найти цитируемый пост)
Да как только я ни пробовал.
Использовал такой код, 
содержимое logfile.txt копировал в файл Temp_logfile.txt'
  • pautina, что из моего предыдущего поста Вам непонятно?
  • Исходники пишущей программы есть? Как файл открывается на запись? 
    На всякий случай повторю еще раз: ShareMode должен быть указан явно, при записи лучше использовать fmShareDenyWrite.
  • Права на доступ к файлу у Вашей учетной записи/группы пользователей есть? Попробуйте открыть его любым текстовым редактором...
  • Бред какой-то... Зачем несколько потоков, копирование из одного потока в другой?
Код

if OpenDialog1.Execute then begin
  FS1:= TFileStream.Create( OpenDialog1.FileName, fmOpenRead or fmShareDenyNone );
  SourceST.LoadFromStream( FS1 );
end;



Автор: pautina 27.1.2009, 20:03
Исходников пищущей программы нет,
При таком коде всё выводится
Код

procedure TForm1.Button1Click(Sender: TObject);

var SourceST,DestST:TStringList;
    i:integer;
    FS1, FS2: TFileStream;
    s:string;

begin
 SourceST:=TStringList.Create;
 DestST:=TStringList.Create;
 // if form1.OpenDialog1.Execute then SourceST.LoadFromFile(form1.OpenDialog1.FileName);
 if OpenDialog1.Execute then
  begin
   // Открываем файл так чтобы к нему пустили
   FS1:= TFileStream.Create(OpenDialog1.FileName, fmShareDenyNone);
   // Сохраняем во временный файл
   FS2:= TFileStream.Create('c:\temp_logfile.txt', fmOpenWrite or fmCreate);
   FS2.CopyFrom (FS1, FS1.Size);
   FS1.Free;
   FS2.Free;
   // Берем содержимое из временного файла
   SourceST.LoadFromFile('c:\temp_logfile.txt');

 for i:=0 to SourceST.Count-1 do
 begin

  try
    // Вывод временных меток
    if pos(':',SourceST[i])<>0 then // Если строка с : найдена
    SourceST[i]:=Copy(SourceST[i],Length(SourceST[i])-19,20)
    else
    // Вывод чисел
     if ((pos('|',SourceST[i])<>0) and ((pos('1',SourceST[i])<>0)
         or (pos('2',SourceST[i])<>0) or (pos('3',SourceST[i])<>0)
         or (pos('4',SourceST[i])<>0) or (pos('5',SourceST[i])<>0)
         or (pos('6',SourceST[i])<>0) or (pos('7',SourceST[i])<>0)
         or (pos('8',SourceST[i])<>0) or (pos('9',SourceST[i])<>0)
         or (pos('0',SourceST[i])<>0)))

     then // Если строка с разделителем | найдена и в строке есть цыфры
     SourceST[i]:=Copy(SourceST[i],Length(SourceST[i])-47,48)
    // Если ни временных меток ни чисел нет то строка пустая
    else SourceST[i]:='';
    DestST.Add(SourceST[i]);
  except
  end;

 end;
 DestST.SaveToFile('112.xls'); //   DestST.SaveToFile('112.txt');   Cохренение в xls-ий файл
 SourceST.Free;
 DestST.Free;
end;
end;

Спасибо за помощь.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)