Работа с TMemoryStream

Тема в разделе "Delphi - Компоненты", создана пользователем morte, 7 апр 2005.

Статус темы:
Закрыта.
  1. morte

    morte Гость

    Вообщем есть переменная data типа TMemoryStream.
    В ней данные следущего вида:
    пер1|пер2|пер3|пер4|пер5|
    пер6|пер7|пер8|пер9|пер10|
    ......
    и так далее.

    Как зделать чтобы программа прочитала строки из data по одной?
    Мне в принципе надо осуществлять поиск в data найти например пер1 и вывести всю строку т.е. пер1|пер2|пер3|пер4|пер5|
     
  2. Barmutik

    Barmutik Гость

    А чем плох вариант пробежаться по памятии найти то что надо?

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

    Быстро и просто вроде ... или там какие-то требования ещё ?
     
  3. morte

    morte Гость

    Нет ну можно и так конечно, но просто таких переменных будет штук 6. И быстрее будет если прога будет искать в определённой, в data например а не во всей памяти сразу.
    А можно пример какой-нибудь? B)
     
  4. Barmutik

    Barmutik Гость

    Что-то я как-то не уловил ... каких переменных будет 6 штук?

    И вот ещё .. Ваши перХ они одного типа ? И разделитель между мини одинаковый ?И что значит что они по строчкам ?
    Просто имеется ввиду что считается что 5 и значит строчка и так далее ?
     
  5. morte

    morte Гость

    Ну вобщем так, всё с начала - есть файл, он зашифрован компонентом DCPcrypt 2 (метод blowfish), программа берёт этот файл дешифрует и результат заносит в переменную data типа TMemoryStream (чтобы не сохранять расшифрованный файл на диске, а просто работать с ним из памяти).
    Выглядит это так:

    Код (Text):
    procedure TForm1.FormCreate(Sender: TObject);
    var
     Cipher: TDCP_cipher;         // the cipher to use
     CipherIV: array of byte;     // the initialisation vector (for chaining modes)
     Hash: TDCP_hash;             // the hash to use
     HashDigest: array of byte;   // the result of hashing the passphrase with the salt
     Salt: array[0..7] of byte;   // a random salt to help prevent precomputated attacks
     strmInput: TFileStream;
     strmOutput: TMemoryStream;
    begin
     strmInput := nil;
     strmOutput := nil;
     try
       strmInput := TFileStream.Create('data/encrypt.db',fmOpenRead);
       strmOutput := TMemoryStream.Create;
       Hash := TDCP_hash(DCP_haval1);
       SetLength(HashDigest,Hash.HashSize div 8);
       strmInput.ReadBuffer(Salt[0],Sizeof(Salt));  // read the salt in from the file
       Hash.Init;
       Hash.Update(Salt[0],Sizeof(Salt));   // hash the salt
       Hash.UpdateStr('pass');  // and the passphrase
       Hash.Final(HashDigest[0]);           // store the hash in HashDigest
       Cipher := TDCP_cipher(DCP_blowfish1);
       if (Cipher is TDCP_blockcipher) then            // if it is a block cipher we need the IV
       begin
         SetLength(CipherIV,TDCP_blockcipher(Cipher).BlockSize div 8);
         strmInput.ReadBuffer(CipherIV[0],Length(CipherIV));       // read the initialisation vector from the file
         Cipher.Init(HashDigest[0],Min(Cipher.MaxKeySize,Hash.HashSize),CipherIV);  // initialise the cipher
         TDCP_blockcipher(Cipher).CipherMode := cmCBC;
       end
       else
       Cipher.Init(HashDigest[0],Min(Cipher.MaxKeySize,Hash.HashSize),nil);  // initialise the cipher
       Cipher.DecryptStream(strmInput,strmOutput,strmInput.Size - strmInput.Position); // decrypt!
       Cipher.Burn;
       strmInput.Free;
    //  strmOutput.Free;
       MessageDlg('File decrypted',mtInformation,[mbOK],0);
     except
       strmInput.Free;
       strmOutput.Free;
       MessageDlg('Ошибка при расшифровке файла базы данных, обратитесь к разработчику.',mtError,[mbOK],0);
     end;
    end;
    Расшифрованные даные выглядят следущим образом:
    Все переменные - это обычный текст string т.е.
    Да разделители одинаковы - |
     
  6. Barmutik

    Barmutik Гость

    Ну можно что-то типа такого:

    Код (Text):
    function StartsBuffer(ASubBuffer: Pointer; ASubBufferSize: Cardinal;
    ABuffer: Pointer; ABufferSize: Cardinal): Boolean;
    begin
    if ASubBufferSize <= ABufferSize then
     Result := CompareMem(ASubBuffer, ABuffer, ASubBufferSize)
    else
     Result := False;
    end;

    var
    AStream: TMemoryStream;
    I: Integer;
    AFindStr: PChar;
    AFindLength: Integer;
    begin
    ... дописать откуда стрим и поместить что надо искать в AFindStr, AFindLength - длина того что ищем
    for I := 0 to AStream.Size - 1 do
    begin
     if StartsBuffer(AFindStr, AFindLength, Pointer(Int64(AStream.Memory) + I), AStream.Size - I) then
     begin
      AStream.Seek(I, soFromBeginning);
      // сейчас находимся в том месте где нашли заданный фрагмент, теперь просто сместится в обе стороны
        до символа #13 и потом прочитать в буфер строку от начала до конца.
     end;
    end;
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей