Работа с TMemoryStream

  • Автор темы morte
  • Дата начала
Статус
Закрыто для дальнейших ответов.
M

morte

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

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

Barmutik

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

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

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

morte

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

Barmutik

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

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

morte

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

Код:
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;
Расшифрованные даные выглядят следущим образом:
373700|STRING|N/A|STRING|800-635-5955
373701|STRING2|N/A|STRING|800-635-5955
373702|STRING3|N/A|STRING|800-635-5955
... и так далее ещё 2000 строк
Все переменные - это обычный текст string т.е.
Да разделители одинаковы - |
 
B

Barmutik

Гость
#6
Ну можно что-то типа такого:

Код:
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;
 
Статус
Закрыто для дальнейших ответов.