Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.01.2013, 01:25   #1
record222
Форумчанин
 
Регистрация: 23.09.2009
Сообщений: 127
По умолчанию Работа с большими txt

Доброе время суток друзья!
Подскажите пожалуйста как правильно работать с файлами больше 50к строк. Как быстро их обрабатывать?

На данный момент пользуюсь такой конструкцией. Но она очень долго обрабатывает строки.

Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
  data:=tstringlist.Create;
  try
 data.LoadFromFile('Output_'+inttostr(number)+'.txt');
  except
  ShowMessage('Файлы кончились!');
  end;
sleep(1500);
work:=true;
for thread := 1 to 100 do dasdas.Create(false);
end;

procedure dasdas.Execute;
var
cou:integer;
s:string;
s_ban:string;
begin
  inherited;
     while work do
 begin
if cou>data.Count-1 then
 begin
work:=false;
 end
else
begin
s:=data[cou];
cou:=cou+1;
Дальше идет обработка строки... Функции пос и т.д..
end;
end;
 end;
data.Free;
end;
record222 вне форума Ответить с цитированием
Старый 11.01.2013, 07:09   #2
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

работа не показана...
50к - небольшой файл...

показывай работу
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 11.01.2013, 08:33   #3
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

и ещё, я вообще не понимаю, зачем создавать 100 (СТО !!!!) потоков для обработки одного текста!
Но ещё больше не понимаю, зачем это делать, с учётом того, что (при первом взгляде на код) похоже, что все 100 потоков обрабатывают одни и те же строки.
Получаем (время на обработку одной строки) * (число строк) * 100 (число потоков) + 100*(накладные расходы_на каждый поток)
не проще ли обрабатывать в одном потоке, тогда время будет: (время на обработку одной строки) * (число строк)
Serge_Bliznykov вне форума Ответить с цитированием
Старый 11.01.2013, 11:59   #4
record222
Форумчанин
 
Регистрация: 23.09.2009
Сообщений: 127
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
и ещё, я вообще не понимаю, зачем создавать 100 (СТО !!!!) потоков для обработки одного текста!
Но ещё больше не понимаю, зачем это делать, с учётом того, что (при первом взгляде на код) похоже, что все 100 потоков обрабатывают одни и те же строки.
Получаем (время на обработку одной строки) * (число строк) * 100 (число потоков) + 100*(накладные расходы_на каждый поток)
не проще ли обрабатывать в одном потоке, тогда время будет: (время на обработку одной строки) * (число строк)
Создание потока делал на одном из примеров... Теперь понял, что смысла так делать нет...

Последний раз редактировалось record222; 11.01.2013 в 12:04.
record222 вне форума Ответить с цитированием
Старый 11.01.2013, 12:01   #5
record222
Форумчанин
 
Регистрация: 23.09.2009
Сообщений: 127
По умолчанию

Цитата:
Сообщение от Slym Посмотреть сообщение
работа не показана...
50к - небольшой файл...

показывай работу
Вот полный код потока

Код:
procedure dasdas.Execute;
var
cou:integer;
s:string;
s_ban:string;
begin
  inherited;
     while work do
 begin
if cou>data.Count-1 then
 begin
work:=false;
 end
else
begin
s:=data[cou];
cou:=cou+1;
if POS('text', s)>0 then
begin
s_ban:=copy(s,0, pos(' -', s)-1);
   banstr_1.Add(s_ban);
   banstr_1.SaveToFile('ban_1.txt');
   form1.statusbar1.SimpleText:='Кол-во 1 в базе: '+inttostr(banstr_1.Count-1);
   form1.StatusBar2.SimpleText:='Количество строк: '+inttostr(data.Count-1)+ '; Обработано: '+inttostr(cou) + '; Осталось: '+inttostr(data.Count-1-cou);
//showmessage(s_ban);
end else begin
  if POS('text', s)>0 then      begin
s_ban:=copy(s,0, pos(' -', s)-1);
banstr_2.Add(s_ban);
   banstr_2.SaveToFile('ban_2.txt');
   form1.statusbar3.SimpleText:='Кол-во 2 в базе: '+inttostr(banstr_2.Count-1);
   form1.StatusBar2.SimpleText:='Количество строк: '+inttostr(data.Count-1)+ '; Обработано: '+inttostr(cou) + '; Осталось: '+inttostr(data.Count-1-cou);
  end else
  begin
   form1.statusbar1.SimpleText:='Кол-во 1 в базе: '+inttostr(banstr_1.Count-1);
    form1.statusbar3.SimpleText:='Кол-во 2 в базе: '+inttostr(banstr_2.Count-1);
   form1.StatusBar2.SimpleText:='Количество строк: '+inttostr(data.Count-1)+ '; Обработано: '+inttostr(cou) + '; Осталось: '+inttostr(data.Count-1-cou);
  end;
end;
end;
 end;
data.Free;
end;
record222 вне форума Ответить с цитированием
Старый 11.01.2013, 12:10   #6
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

правильно... а теперь максимально запакованный образец файла сюда...
а пока позырю код

ба!!! работа со строками смеешся? ты пишешь в файл дважды на итерацию

и чем отличается

if POS('text', s)>0 then
begin
............
end else begin
if POS('text', s)>0 then begin
s_ban:=copy(s,0, pos(' -', s)-1);
banstr_2.Add(s_ban);

про доступ к форме из потока даже молчу....
Не стесняемся, плюсуем!

Последний раз редактировалось Slym; 11.01.2013 в 12:17.
Slym вне форума Ответить с цитированием
Старый 11.01.2013, 12:27   #7
record222
Форумчанин
 
Регистрация: 23.09.2009
Сообщений: 127
По умолчанию

Цитата:
Сообщение от Slym Посмотреть сообщение
правильно... а теперь максимально запакованный образец файла сюда...
а пока позырю код

ба!!! работа со строками смеешся? ты пишешь в файл дважды на итерацию

и чем отличается

if POS('text', s)>0 then
begin
............
end else begin
if POS('text', s)>0 then begin
s_ban:=copy(s,0, pos(' -', s)-1);
banstr_2.Add(s_ban);

про доступ к форме из потока даже молчу....
Файл в личке...
В файле, логи сервера. Которые программа смотрит и выбирает ей нужны USER-Agent и копирует айпи.
Вместо text_1 -> Mozilla
Вместо text_2 -> Opera
record222 вне форума Ответить с цитированием
Старый 11.01.2013, 17:11   #8
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

файл недоступен... 404
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 14.01.2013, 10:12   #9
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
type
  TWorkThread=class(TThread)
  protected
    Counters:array of integer;
    procedure UpdateFormData;
    procedure Execute; override;
  public
    FileName:string;
  end;
{ TWorkThread }

procedure TWorkThread.UpdateFormData;
var j:integer;
s:string;
begin
  //form1.StatusBar2.SimpleText:='Количество строк: '+inttostr(Counters[Length(Counters)]);
  s:='';
  for j:=low(Counters) to high(Counters)-1 do
  begin
    s:=s+Format('Кол-во %d в базе: %d; ',[j+1,Counters[j]]);
  end;
  //form1.statusbar1.SimpleText:=s;
end;

procedure TWorkThread.Execute;
const
  Agent:array[0..1] of string=('Mozilla','Opera','IE');
var
  data:TStringList;
  i,j:integer;
  AgentBuf:array[0..1] of TStringList;
  s:string;
  s_ban:string;
begin
  SetLength(Counters,Length(Agent)+1);
  for j:=low(Agent) to high(Agent) do
    AgentBuf[j]:=TStringList.Create;
  try
    data:=TStringList.Create;
    try
      data.LoadFromFile(FileName);
      for i:=0 to data.Count-1 do
      begin
        s:=data[i];
        for j:=low(Agent) to high(Agent) do
        begin
          if Pos(Agent[j],s)>0 then
          begin
            s_ban:=copy(s,0, pos(' -', s)-1);
            AgentBuf[j].Add(s_ban);
            break;
          end;
        end;
        if (i mod 100)=0 then
        begin
          for j:=low(Agent) to high(Agent) do
            Counters[j]:=AgentBuf[j].Count;
          Counters[Length(Counters)]:=i;
          Synchronize(UpdateFormData);
        end;
      end;
    finally
      data.Free;
    end;
  finally
    for j:=low(Agent) to high(Agent) do
    begin
      AgentBuf[j].SaveToFile('ban_'+IntToStr(j+1)+'.txt');
      AgentBuf[j].Free;
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var WorkThread:TWorkThread;
begin
  WorkThread:=TWorkThread.Create(true);
  WorkThread.FileName:='Output_0.txt';
  WorkThread.FreeOnTerminate:=true;
  WorkThread.Resume;
end;

end.
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с большими файлами. ShamanK C# (си шарп) 12 05.04.2012 19:41
Работа с большими числами tae1980 Microsoft Office Excel 3 25.12.2010 20:41
C++ Работа с большими числами airwind Помощь студентам 4 08.12.2010 15:26
Работа с большими числами SanekIrk Общие вопросы Delphi 3 11.07.2008 22:11
работа с большими числами sasadabest Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 16.10.2007 10:51