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

Вниз

Построчное чтени большого текстового файла   Найти похожие ветки 

 
IceBeerg ©   (2005-09-13 18:26) [0]

Подскажите выход из ситуации... Есть большой log файл (более 40 гигов), пытаюсь загружать его в StringList - читается не весь... Попробовал использовать FileStream, но не знаю как через него читать файл построчно... Цель - читать файл построчно, определять дату находящуюся в начале каждой строки и по этой дате выводить данные log"а. Строки файла НЕ одинаковой длинны...


 
Изя Губерман   (2005-09-13 18:37) [1]


while not EoF(f) do begin
 ReadLn(f, s);
end;


 
Digitman ©   (2005-09-13 18:38) [2]


> Есть большой log файл (более 40 гигов), пытаюсь загружать
> его в StringList - читается не весь


еще бы !

ведь ВАП Win32-процесса ограничен 4-мя Гб, из которых прикл.задаче доступно и того меньше.


> Попробовал использовать FileStream, но не знаю как через
> него читать файл построчно


ну, положим, FileStream явно не предназначен для этого ..

а Assign() + ReadLn() не приходило в голову использовать для оной цели ?

ведь ReadLn() как раз для построчного чтения и предназначен ..


 
isasa ©   (2005-09-13 18:40) [3]

Все равно весь файл :) не влезет читай блоками.

String types
Type Maximum length Memory required Used for
ShortString 255 characters 2 to 256 bytes backward compatibility
AnsiString ~2^31 characters 4 bytes to 2GB 8-bit (ANSI) characters, DBCS ANSI, MBCS ANSI, etc.
WideString ~2^30 characters 4 bytes to 2GB Unicode characters; multi-user servers and multi-language applications


 
PVOzerski ©   (2005-09-13 18:42) [4]

Дык выбор-то невелик. Считываем в строку блок некой "разумной" длины, находим знак(и) перехода на следующую строку. Если не нашли - доращиваем строку следующим блоком. А нашли - строку обрубаем, а по файлу - seek назад, на вычисляемую позицию начала следующей строки... Если постараться, можно усовершенствовать алгоритм так, что при наличии нескольких строк в блоки вытаскивать их всех.

Замечу, что если речь идет действительно о десятках гигабайт (а не мегабайт), придется работать через потоки или WinAPI. А то blockread работает со знаковыми 4-байтными целыми применительно к размерам и индексации блоков - на такую позицию будет не перепрыгнуть :(


 
Котик Бегемотик   (2005-09-13 18:45) [5]

А может уважаемый еще и соизволит обьяснить смысл создания текстового файла такого большого размера ...
40 гигов !!! представляю себе скорость работы с ним :(


 
isasa ©   (2005-09-13 18:48) [6]

PVOzerski ©   (13.09.05 18:42) [4]

В этом плане, можно попробовать

BOOL ReadFile(
 HANDLE hFile,                // handle to file
 LPVOID lpBuffer,             // data buffer
 DWORD nNumberOfBytesToRead,  // number of bytes to read
 LPDWORD lpNumberOfBytesRead, // number of bytes read
 LPOVERLAPPED lpOverlapped    // overlapped buffer
);

DWORD: Longword; //0..4294967295 unsigned 32-bit

Будет быстрее, чем ReadLn(...)


 
IceBeerg ©   (2005-09-13 18:50) [7]

Котик Бегемотик   (13.09.05 18:45) [5]
Это лог 1С за два года!

Изя Губерман   (13.09.05 18:37) [1]
Это первое, что пришло в голову, но медоенно работает...

PVOzerski ©   (13.09.05 18:42) [4]
придется работать через потоки или WinAPI

наведите пожалуйста на район "раскопок" информации по WinAPI, что-то в голову ничего не лезет...


 
Игорь Шевченко ©   (2005-09-13 18:52) [8]

Readln для этого придумана.

Интересно, какой очередной Архангельский рекомендует читать файл путем использования StringList, поубивал бы.

IceBeerg ©   (13.09.05 18:50) [7]


> Это первое, что пришло в голову, но медоенно работает...


Быстрее все равно не сделаешь


 
IceBeerg ©   (2005-09-13 18:53) [9]

isasa ©   (13.09.05 18:48) [6]
в даном моменте то же прийдется использовать метод предложенный PVOzerski по поводу блочного чтения...


 
IceBeerg ©   (2005-09-13 18:55) [10]

Игорь Шевченко ©   (13.09.05 18:52) [8]

> Readln для этого придумана

это еще с Паскаля понятно


> Интересно, какой очередной Архангельский рекомендует
> читать файл путем использования StringList, поубивал
> бы.

никакой, сам лажанулся


> Быстрее все равно не сделаешь

а все же хотелось бы, но видимо никак


 
Игорь Шевченко ©   (2005-09-13 18:59) [11]

IceBeerg ©   (13.09.05 18:55) [10]


>
> никакой, сам лажанулся


Да если бы...Не ты первый в этом форуме :)


> а все же хотелось бы, но видимо никак


А главное - зачем ? Если лог копился два года, то подождать какое-то раумное время всяко можно ?


> в даном моменте то же прийдется использовать метод предложенный
> PVOzerski по поводу блочного чтения...


И зачем изобретать readln, которая делает абсолютно все то же самое ? :)


 
PVOzerski ©   (2005-09-13 18:59) [12]

ReadFile, SetFilePointer. Только проблема поиска знаков перевода каретки остается. На самом деле, TFileStream использует внутри себя эти же функции.


 
PVOzerski ©   (2005-09-13 19:03) [13]

2Игорь Шевченко:
Я не знаю формат лога 1С - может, там не #13#10 :)


 
Anatoly Podgoretsky ©   (2005-09-13 19:28) [14]

PVOzerski ©   (13.09.05 19:03) [13]
Ничего страшного, начиная с Дельфи 6 ReadLn более благосклонен к разделителям строк, по крайней мере Юникс формат понимает, насчет Макинтош неуверен, и еще более не уверен насчет извращеного хакерского формата. LFCR а учитывая как написан 1С там может быть и такое и даже все четыре варианта одновременно.


 
Anatoly Podgoretsky ©   (2005-09-13 19:28) [15]

PVOzerski ©   (13.09.05 18:59) [12]
Проблема поиска решается буферизацией, как это сделано в ReadLn


 
Anatoly Podgoretsky ©   (2005-09-13 19:30) [16]

Еще один хороший путь, это загнать в промышленную базу данных или напрямую, если регулярная структура или через тот же самый ReadLn


 
Fay ©   (2005-09-13 23:38) [17]

2 Игорь Шевченко ©   (13.09.05 18:52) [8]
>> Быстрее все равно не сделаешь
Спорим? 8)


 
Defunct ©   (2005-09-14 01:49) [18]

> IceBeerg

   TLogReader = class
   private
      fFileName   : String;
      fCanRead    : boolean;
      fLastString : String;
      fStream     : TFileStream;
      fStrings    : TStrings;
      fEof        : boolean;
      fErrors     : integer; // Ошибочных строк
      fStartPos   : Int64;   // Позиция начала загрузки
      fLastPos    : Int64;   // Последняя прочитанная позиция
      fNextPos    : Int64;   // Позиция для чтения следующей пачки
      fBatchPos   : Integer; // Позиция внутри порции прочитанных строк
      fLastLoadedString: String;
      fDontCheckMask : boolean;
      fMask          : String;
      fMemo          : TMemo;
      fReverseLookup : boolean;
      fSearching     : boolean;
      fPosFromEnd    : Int64;

      procedure BatchReadFromEnd;
      procedure BatchRead; // читает порцию из лог файла в fStrings
      procedure SetFileName(const Value: String);
      function  ReadString: String;
      procedure SetLastLoadedString(const Value: String);
      function  GetEndPos: Int64;
      function  GetPercentDone: Integer;
      procedure SetMemo(const Value: TMemo);
      procedure Report(const S: String );
      procedure SetReverse(const Value: boolean);
   public
      property FileName: String read fFileName write SetFileName;

      property LastLoadedString:String read fLastLoadedString
               write SetLastLoadedString; // Для инициализации продолжения
      property CanRead: boolean read fCanRead;
      property LastString: String read fLastString;
      property Eof:boolean read fEof;
      property Strings:TStrings read fStrings;
      property StartPosition:Int64 read fStartPos;
      property EndPosition:Int64 read GetEndPos;
      property Progress:Integer read GetPercentDone;
      property ReportBox: TMemo read fMemo write SetMemo;
      property ReverseLookup : boolean read fReverseLookup write SetReverse;

      constructor Create;dynamic;
      destructor Destroy;override;
   end;

{ TLogReader }

constructor TLogReader.Create;
begin
  fFileName := "";
  fMemo := nil;
  fLastString := "";
  fLastLoadedString := "";
  fCanRead := false;
  fStream := nil;
  fEof := True;
  fDontCheckMask := false;
  fStrings := TStringList.Create;
end;

procedure TLogReader.Report(const S: String);
begin
 if Assigned( fMemo ) then
    fMemo.Lines.Add( S );
end;

procedure TLogReader.SetMemo(const Value: TMemo);
begin
 fMemo := Value;
 fMemo.Lines.Clear;
end;

procedure TLogReader.SetReverse(const Value: boolean);
begin
 fReverseLookup := Value;
 if fReverseLookup then
    Report("setting lookup reverse=TRUE (searching from END of stream)")
 else
    Report("setting lookup reverse=FALSE (searching from BEGIN of stream");
end;

procedure TLogReader.SetFileName(const Value: String);
begin
 Report("setting log file name = " + Value );
 fCanRead := FileExists( Value );
 if Assigned(fStream) then
    FreeAndNil( fStream );

 if CanRead then
    begin
       fFileName := Value;
       fStream := TFileStream.Create( fFileName, fmOpenRead or fmShareDenyNone );
       fNextPos := 0;
       fStartPos := 0;
       fLastPos := 0;
       fStrings.Clear;
       fEof := fStream.Size = 0;
       fPosFromEnd := fStream.Size;
       BatchRead;
       Report("Assigned filename has open successfully");
    end
 else
    begin
       fFileName := "";
       Report("Assigned filename not found, reseting filename");
    end;
end;

procedure TLogReader.BatchReadFromEnd;
var
  S : String;
  i : integer;

  function GetBatchPos:Int64;
  begin
     Result := fPosFromEnd - lrBatchSize;
     if Result < 0 then
        Result := 0;
  end;

begin
  Report("Trying to do batch read (direction=right to left)");
  fNextPos := fPosFromEnd;
  Report("Current batch position ="+ IntToStr( fNextPos ));
  fPosFromEnd := GetBatchPos;
  fLastPos := fPosFromEnd;
  fStream.Position := fPosFromEnd;

  SetLength( S, lrBatchSize );
  SetLength( S, fStream.Read( S[1], lrBatchSize ) );

  for i := 1 to Length(S) do
     if S[i] = #10 then break;

  fPosFromEnd := fPosFromEnd + i;

  fStrings.Text := Copy(S, i + 1, Length(S) - i) ;
  Report("batch read (direction=right to left) success, alloc. StrCount="+
          IntToStr( fStrings.Count ) );
  fBatchPos := 0;
end;

procedure TLogReader.BatchRead;
var
  S : String;
  i : integer;
begin
  if CanRead then
  try
     Report("Trying to do batch read");
     fStream.Position := fNextPos;
     Report("Current batch position ="+ IntToStr( fNextPos ));
     fLastPos := fNextPos;
     SetLength( S, lrBatchSize );
     SetLength( S, fStream.Read( S[1], lrBatchSize ) );

     for i := Length( S ) - 3 downto 1 do
         if S[i] = #10 then break;

     fNextPos := fNextPos + i;

     if i > 2 then
       fStrings.Text := Copy( S, 1, i-2)
     else
       fStrings.Text := Copy( S, 1, i);

     Report("batch read success, allocated stringcount="+IntToStr( fStrings.Count ) );

     fBatchPos := 0;
  except
     on E:Exception do ShowException("BatchRead", ClassName, E)
  end;
end;

function TLogReader.ReadString;
begin
 Result := "";
 if CanRead and (fStrings.Count > 0) then
 begin
    if fBatchPos < fStrings.Count then
       begin
          Result := fStrings.Strings[fBatchPos];
          inc(fBatchPos);
          if not fDontCheckMask then
          if (pos(fMask, Result) = 0) and (fBatchPos < fStrings.Count) then
          begin
             inc( fErrors );
             Result := ReadString;
          end;
       end
    else
       begin
          if fSearching and fReverseLookup then
             BatchReadFromEnd
          else
             BatchRead;
          Result := ReadString;
       end;
 end;

 fEof := Length(Result) = 0;
 if not fEof then
    fLastString := Result

end;


 
Defunct ©   (2005-09-14 01:50) [19]

Продолжение..

procedure TLogReader.SetLastLoadedString(const Value: String);
var
 S: String;
begin
 if Value <> "" then
   try
      Report("setting LLS to locate correct stream position");
      Report("incoming LLS = "+Value);
      fSearching := True;
      if fReverseLookup then BatchReadFromEnd;

      fLastLoadedString := Value;  // будем искать эту строку в файле
      if CanRead then
         begin
            S := ReadString;
            while (Pos(fLastLoadedString, S)=0) and (not EOf) do
               S := ReadString;
            fStartPos := fLastPos;
         end;
      Report("LLS detected at stream postion = " + IntToStr( fLastPos ) );
      Report("LLS`s batch position = " + IntToStr( fBatchPos ) );
   finally
      fSearching := false;
   end
 else
   begin
      Report("there is no selected LLS, stream will be read from begin");
   end;
end;

function TLogReader.GetEndPos: Int64;
begin
  if Assigned( fStream ) then
     Result := fStream.Size
  else
     Result := 0;
end;

function TLogReader.GetPercentDone: integer;
begin
  Result := 100;
  if Assigned( fStream ) then
     if EndPosition - StartPosition > 0 then
     begin
       Result := Round( Result * (fStream.Position - StartPosition)/
                     (EndPosition - StartPosition) )
     end
end;

destructor TLogReader.Destroy;
begin
 Report("exiting log reader");
 FreeAndNil( fStream );
 FreeAndNil( fStrings );
 inherited;
end;


 
Alexander Panov ©   (2005-09-14 02:02) [20]

IceBeerg ©   (13.09.05 18:26)

Как вариант - разбить файл на куски приемлимого размера, каждому файлу дать имя, в которое входит значение начальной и конечной даты, обрабатывать нужный файл в зависимости от даты.


 
Defunct ©   (2005-09-14 02:12) [21]

Пример применения:

   TMyLogReader = class( TLogReader)
   public
      function GetString: String;
      constructor Create;override;
   end;

constructor TMyLogReader.Create;
begin
 inherited;
 fDontCheckMask := True;
end;

function TMailLogReader.GetString: TMailRecord;
var
  BackupLastString : String;
begin
  BackupLastString := fLastString;
  Result := ReadString;
  if  Result = "" then
     fLastString := BackupLastString
end;


Для чтения с начала:

var
  LLS : String;

 ...
 with TMyLogReader do
 try
     ReportBox := Memo1;
     ReverseLookup := False;
     FileName := "some.log"
     LastLoadedString := "";
     
     while not Eof do
     begin
         LLS := GetString;
         ...
     end;
     <Новая последняя прочитанная строка> := LastString;
 finally
     free;
 end;


Для добавления новых записей с определенной позиции:

var
  LLS : String;

 ...
 with TMyLogReader do
 try
     ReportBox := Memo1;
     ReverseLookup := True;
     FileName := "some.log"
     LastLoadedString := <Сохраненная последняя прочитанная строка>;
     
     while not Eof do
     begin
         LLS := GetString;
         ...
     end;
     <Новая последняя прочитанная строка> := LastString;
 finally
     free;
 end;


 
Defunct ©   (2005-09-14 02:22) [22]

Работает этот LogReaded так:

1. читает порцию данных из стрима, которая определяется константой lrBactchSize в байтах. (оптимальнее всего ~1Mb) в TStrings
2. выкусывает обрывки строк из TStrings, и корректирует абсолютную позицию в файле для чтения следующей порции строк.
3. Ключевой метод - ReadString, последовательно выдает все строки открытого лог файла.
4. Читать лог файл можно с определенной позиции, которая определяется при задании "последней прочитанной строки" (свойство LastLoadedString), имеется два способа поиска позиции - с начала файла и с конца, задается свойством ReversLookup. (поиск с конца значительно ускоряет процесс поиска позиции искомой строки, если искомая строка находится ближе к концу лог файла).


 
Defunct ©   (2005-09-14 02:25) [23]

Defunct ©   (14.09.05 02:12) [21]

допустил пару ошибок в [21]:

function TMyLogReader.GetString: String;
with TMyLogReader.Create do


 
kaif ©   (2005-09-14 02:28) [24]

Я бы для начала разрезал этот файл на 400 файлов равной длины, как советует Panov.
И лазил бы лишь туда, куда мне интересно лазить. Например, по дате.
Читал бы с помощью TFileStream блоками по 32K.
Внутри блоков искал бы символ возврата каретки.
Если что-то полезное нашел бы в этих файлах - перегнал бы в базу данных, а все бесполезное выкинул бы к чертям.


 
Defunct ©   (2005-09-14 02:36) [25]

kaif ©   (14.09.05 02:28) [24]

Log файл может постоянно дописываться. Класс [18] предназначен для работы с постоянно открытым Log файлом, т.е. приложение ведет себе лог, а мы подчитываем себе в базу только новые записи при необходимости. Бить файл на много мелких imho абсолютно не нужно. Проще добавить в базу все что надо и стереть весь этот лог.


 
Gydvin ©   (2005-09-14 06:27) [26]

Попробуй это. Только надо знать кол-во строк в файле.

function GrabLine(const AFileName: string; ALine: Integer): string;
var
  fs: TFileStream;
  buf: packed array[0..4095] of Char;
  bufRead: Integer;
  bufPos: PChar;
  lineStart: PChar;
  tmp: string;
begin
  fs := TFileStream.Create(AFileName, fmOpenRead);
  try
    Dec(ALine);
    bufRead := 0;
    bufPos := nil;

    { read the first line specially }
    if ALine = 0 then
    begin
      bufRead := fs.Read(buf, SizeOf(buf));
      if bufRead = 0 then
        raise Exception.Create("Line not found");
      bufPos := buf;
    end else
      while ALine > 0 do
      begin
        { read in a buffer }
        bufRead := fs.Read(buf, SizeOf(buf));
        if bufRead = 0 then
          raise Exception.Create("Line not found");
        bufPos := buf;
        while (bufRead > 0) and (ALine > 0) do
        begin
          if bufPos^ = #10 then
            Dec(ALine);
          Inc(bufPos);
          Dec(bufRead);
        end;
      end;
    { Found the beginning of the line at bufPos... scan for end.
     2 cases:
       1) we"ll find it before the end of this buffer
       2) it"ll go beyond this buffer and into n more buffers }
    lineStart := bufPos;
    while (bufRead > 0) and (bufPos^ <> #10) do
    begin
      Inc(bufPos);
      Dec(bufRead);
    end;
    { if bufRead is positive, we"ll have found the end and we can leave. }
    SetString(Result, lineStart, bufPos - lineStart);
    { determine if there are more buffers to process }
    while bufRead = 0 do
    begin
      bufRead := fs.Read(buf, SizeOf(buf));
      lineStart := buf;
      bufPos := buf;
      while (bufRead > 0) and (bufPos^ <> #10) do
      begin
        Inc(bufPos);
        Dec(bufRead);
      end;
      SetString(tmp, lineStart, bufPos - lineStart);
      Result := Result + tmp;
    end;
  finally
    fs.Free;

  end;
  delete(Result,length(Result),1);
end;


 
Fay ©   (2005-09-14 06:51) [27]

2 Alexander Panov ©   (14.09.05 2:02) [20]
Хрень получится. К тому же, если не ошибаюсь, 1C-у это не понравится.
Лучше создать файл со смещениями строк.


 
KilkennyCat ©   (2005-09-14 08:00) [28]


> 1C-у это не понравится.

а не надо им говорить.


 
Fay ©   (2005-09-14 08:21) [29]

2 KilkennyCat ©   (14.09.05 8:00) [28]
Я ваще не спец по 1С Пр-е, но мне как-то запомнилось, что он матерится на изменение лога.


 
KilkennyCat ©   (2005-09-14 08:58) [30]


> [29] Fay ©   (14.09.05 08:21)

то есть, он отслеживает изменение ТАКОГО лога?! когда ж он основным делом занят? :))


 
Fay ©   (2005-09-14 09:38) [31]

KilkennyCat ©   (14.09.05 8:58) [30]
Он отслеживает при "запуске", после чего файл занят монопольно.


 
Игорь Шевченко ©   (2005-09-14 10:00) [32]

Fay ©   (13.09.05 23:38) [17]


> >> Быстрее все равно не сделаешь
> Спорим? 8)


А как меряться будешь ? :)

Я уже проводил подобные измерения, ReadLn работает достаточно быстро.


 
Fay ©   (2005-09-14 10:03) [33]

2 Игорь Шевченко ©   (14.09.05 10:00) [32]

>> ReadLn работает достаточно быстро.

Но не ultimate 8)


 
Игорь Шевченко ©   (2005-09-14 10:15) [34]

Fay ©   (14.09.05 10:03) [33]

Хорошо, давай ты проведешь эксперимент - создашь текстовый файл на 40 Гб, и почитаешь его разными способами. Только перед каждым чтением необходимо выключать компьютер, чтобы исключить побочный эффект кеширования и аппаратной буферизации :)

Результаты можно выложить в этой ветке.


 
Fay ©   (2005-09-14 10:20) [35]

2 Игорь Шевченко ©   (14.09.05 10:15) [34]
У меня есть только 17Gb


 
IceBeerg ©   (2005-09-14 10:21) [36]

PVOzerski ©   (13.09.05 19:03) [13]
Я не знаю формат лога 1С - может, там не #13#10 :)

Нормальный там формат - #13#10

Alexander Panov ©   (14.09.05 2:02) [20]
Как вариант - разбить файл на куски приемлимого размера

тоже идея

kaif ©   (14.09.05 2:28) [24]
Читал бы с помощью TFileStream блоками по 32K.

мне рекомендовали по 8 или 16К

Defunct ©   (14.09.05 2:36) [25]
Log файл может постоянно дописываться

именно это и происходит

Fay ©   (14.09.05 6:51) [27]
1C-у это не понравится

а хто его спашифать будет?

Fay ©   (14.09.05 8:21) [29]
Я ваще не спец по 1С Пр-е, но мне как-то запомнилось, что он матерится на изменение лога.

молодец, честно признался, нихрена он не матрится на изменеия лога. Я свои действия скрывал так: открыл лог в FAR"е убил нужные строки и вышел с сохранением и никаких тело-прграммо-движений по этому поводу в 1С не наблюдалось...

Fay ©   (14.09.05 9:38) [31]
после чего файл занят монопольно

нет, не занять монопольно, а то как бы 6 юзверей туда инфу писали?

Игорь Шевченко ©   (14.09.05 10:00) [32]
Я уже проводил подобные измерения, ReadLn работает достаточно быстро

наверное всетаки воспользуюсь ReadLn и нафик изобретать велосипед...

И ВООБЩЕ МУЖИКИ, ВСЕМ БОЛЬШОЕ СПАСИБО, ЗА РЕАЛИЗАЦИИ (КОД) ОТДЕЛЬНОЕ! БУДУ ПРОБОВАТЬ...


 
Игорь Шевченко ©   (2005-09-14 10:32) [37]

Fay ©   (14.09.05 10:20) [35]

Вот давай ты 10 Гб выделишь под файл и будешь развлекаться. Мне интересно, насколько оно быстрее получится в твоем варианте.


 
IceBeerg ©   (2005-09-14 10:52) [38]

Качайте реальный - 44045783 байт, в RAR архиве 2832442 байт. www.icebeerg.newmail.ru/1cv7.rar


 
Fay ©   (2005-09-14 10:55) [39]

2 IceBeerg ©   (14.09.05 10:52) [38]
Не наш размер 8)
Но данные вполне пойдут для заполнения


 
Игорь Шевченко ©   (2005-09-14 11:03) [40]

IceBeerg ©   (14.09.05 10:52) [38]

Вроде ты другой размер указывал в начале ?



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2005.10.09;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.59 MB
Время: 0.016 c
14-1127126807
pazitron_brain
2005-09-19 14:46
2005.10.09
GTA : VC по сети.


14-1126772979
Игорь Шевченко
2005-09-15 12:29
2005.10.09
Поговорим об именах или что в имени тебе моем...


1-1126776541
ORMADA
2005-09-15 13:29
2005.10.09
FastDIB


2-1125055920
KyRo
2005-08-26 15:32
2005.10.09
Как отслеживать первую запись ?


14-1125643750
Lexer
2005-09-02 10:49
2005.10.09
Злобный вирус POKAPOKA63





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский