Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.04.30;
Скачать: CL | DM;

Вниз

Как записать в бинарный файл данные String   Найти похожие ветки 

 
.Кирилл   (2006-03-24 15:32) [0]

Здравствуйте! Подскажите, есть строка, ее шифрую (ф-я ниже), необходимо сохр. как двоичные данные в файл. Ложил как текстовую, обратно не расшифровывается в некоторых случаях, т.е. в текст сохранять нельзя.

Проблема, не могу "запихнуть" строку в двоичный файл. Как делал:
var
s: string;
TF: file of byte;
b:byte;
i:integer;
begin
 s:=Encrypt(Memo1.Lines.Text, 1000);
 AssignFile(TF, "C:\test.bin");
 ReWrite(TF);
 for i:=0 to length(s)-1 do
  begin
   b:=Byte(???(s[i])???);
   blockwrite(TF, b, 1);
  end;
 CloseFile(TF);


тут не могу привести к байту очередной символ :(

Функции шифрования:

const
 C1 = 10000;  
 C2 = 20000;  

function Decrypt(const S: String; Key: Word): String;
var
  I: Integer;
begin
Result := S;
for I := 1 to Length(S) do
  begin
   Result[I] := char(byte(S[I]) xor (Key shr 8));
   Key := (byte(S[I]) + Key) * C1 + C2;
  end;
end;

function Encrypt(const S: String; Key: Word): String;
var
  I: Integer;
begin
 Result := S;
 for I := 1 to Length(S) do
     begin
          Result[I] := char(byte(S[I]) xor (Key shr 8));
          Key := (byte(Result[I]) + Key) * C1 + C2;
     end;
end;


 
.Кирилл   (2006-03-24 15:34) [1]

И ещё, если можно, покажите как прочитать этот файл потом из своей программы самым простым методом (и данные например вывести в memo и т.п.)


 
MU ©   (2006-03-24 15:54) [2]


> for i:=0 to length(s)-1 do


for i:=1 to length(S) do


 
MU ©   (2006-03-24 15:57) [3]

Кирилл   (24.03.06 15:34) [1]
 Memo1.Lines.LoadFromFile("C:\test.bin");


 
Плохиш ©   (2006-03-24 16:08) [4]


> Как записать в бинарный файл данные String
>
> .Кирилл   (24.03.06 15:32)  

TFileStream


 
Jeer ©   (2006-03-24 17:37) [5]

.Кирилл   (24.03.06 15:32)

Есть печатные символы, есть служебные для текста, есть иные.
Разберись с этим - станет ясно, почему бинарному файлу все равно, а текстовому - нет, принимать в себя результать шифрации строки.


 
Чародей ©   (2006-03-24 19:50) [6]


> b:=Byte(???(s[i])???);

b:=ord(s[i]);
обратно
s[i]:=chr(b);


 
.Кирилл ©   (2006-03-25 10:47) [7]

Здравствуйте! Спасибо большое всем за ответы, попробовал, компилируется нормально, но вот на выходе получается не тот текст

 //шифруем строку
 s:=Encrypt("Это зашифрованная строка", 1000);

 //создаем файл, что бы туда записать данные
 AssignFile(TF, "C:\test.bin");
 ReWrite(TF);
 for i:=0 to length(s)-1 do
  begin
   b:=Byte(ord(S[i]));
   blockwrite(TF, b, 1);
  end;
 CloseFile(TF);

 //открываем этот файл для чтения и пытаемся расшифровать
 s:="";
 SetLength(s,1000); //вот тут проблемка... как бы установить размер
      //переменной, что бы в нее вошло все содержимое файла?
 AssignFile(TF, "C:\test.bin");
 Reset(TF);
 While not eof(TF) do
  begin
   blockread(TF, b, 1);
   s[i]:=Chr(b);
  end;
 Memo3.Lines.Text:=Decrypt(s, 1000);


В Memo3.Lines.Text показывается абракатабра :( Факт тот, что видимо в файл или не так пишу, или из него не так читаю, подскажите гуру, что делаю не так при записи/чтения в файл?


 
Чародей ©   (2006-03-25 11:50) [8]


> for i:=0 to length(s)-1 do

for i:=1 to length(s) do
В строках индекс нпсинается с 1


> b:=Byte(ord(S[i]));

b:=ord(s[i]);
Фунтция ord уже вожвращает byte


> Reset(TF);
>  While not eof(TF) do
>   begin
>    blockread(TF, b, 1);
>    s[i]:=Chr(b);
>   end;

Reset(TF);
i:=1;
While not eof(TF) do
  begin
  blockread(TF, b, 1);
  s[i]:=Chr(b);
 inc(i);
 end;

tf:file of byte;
Вместо blockwrite используй Write(tf,b);

Тьфу блин, короче это работает:
var s:string;
  tf:file of byte;
  i:integer;
  b:byte;
begin
s:="Ýòî çàøèôðîâàííàÿ ñòðîêà";
AssignFile(TF, "C:\test.bin");
ReWrite(TF);
for i:=1 to length(s) do
 begin
  b:=ord(S[i]);
  Write(tf,b);
 end;
s:="";
SetLength(s,FileSize(tf));
Reset(TF);
i:=1;
While not eof(TF) do
 begin
  Read(TF, b);
  s[i]:=Chr(b);
  inc(i);
 end;
CloseFile(TF);


 
DevilDevil ©   (2006-03-26 09:04) [9]

Да...
Вообще, забудь про эти AssignFile, ReWrite, CloseFile... брр...
Существуют более удобные классы: TFileStream и TMemoryStream. Первый - для чтения\записи в файл, второй - в память. Подробно описывать не буду, но:

// запись
...
len : byte;
S : string;
F : TFileStream;
begin
  ...
  len := length(S);
  // fmCreate - создать файл
  F := TFileStream.Create("C:\test.bin", fmCreate);
  // для чтения\записи используй fmOpenReadWrite
  F.Write(len, 1);
  F.Write(S[1], len);// или for i := 1 to len do F.Write(S[i], 1);
  F.Free;                                    
end;

//чтение
...
  F := TFileStream.Create("C:\test.bin", fmOpenReadWrite);
  F.Position := 0;// на всякий случай
  F.Read(len, 1);
  SetLength(S, len);
  F.Read(S[1], len);
  F.Free;

// чтение в Memo
  ...
  F := TFileStream.Create("C:\test.bin", fmOpenReadWrite);
  F.Position := 0;// на всякий случай
  Memo1.Lines.LoadFromStream(F);
  F.Free;


 
.Кирилл ©   (2006-03-26 12:28) [10]

Чародей ©   (25.03.06 11:50)
DevilDevil ©   (26.03.06 09:04)

Спасибо огромное за помощь! Теперь понятно как с этим общатся, прочитал различные справки, ничего не понял в отличие от этих примеров! Один вопрос, сохранение в данном случае ограничивается строкой в 256 символов? (len := length(S); //len : byte;), и в принципе можно увеличить это до 65536, если переменную len сделать WORD? Пока задам вопрос, и сам претестирую :) О результатах напишу.


 
.Кирилл ©   (2006-03-26 13:00) [11]

Оттестировал, все хорошо, пишет в файл столько, сколько надо (свои функции шифрования я пока не использую, сохр. просто строку), т.е. например, если сделать for i:=1 to 10000 do, в даном коде создастся файл в 14кб. А вот прочитать его весь никак не могу :( Вернее с помощью Memo3.Lines.LoadFromStream(F); читается все, но если читать просто в переменную S, читается только символов 100, или меньше.

И ещё вопрос возник, в начале и конце файла вставляются различные символы, и если читать с помощью Memo3.Lines.LoadFromStream(F);, эти символы показываются, хотя их я не формировал, один в начале второй в конце файла. Также эти два символа (точка и т.п.) видны по F3 если нажать в TotalCommander. Т.е. LoadFromStream если с текстом только работает, то ее использовать не буду.


//вот тут все хорошо, пишет файл, все без проблем
procedure TForm1.Button3Click(Sender: TObject);
var
len : word;
S : string;
F : TFileStream;
i :integer;
begin
 s:="";
 for i:=1 to 100 do           //тут формирую строку
  s:=s+IntToStr(i)+") "+#13#10;
 len := length(S);
 F := TFileStream.Create("C:\test.bin", fmCreate);
 F.Write(len, 1);
 for i := 1 to len
  do F.Write(S[i], 1);
 F.Free;
end;

//а вот тут тоже нормально :),
//но читает только из любого файла только первые ~100 (байт или символов)
//а хотелось бы, если файл 15 кб, весь его и считать :(
procedure TForm1.Button4Click(Sender: TObject);
var
len : word;
S : string;
F : TFileStream;
i :integer;
begin
 F := TFileStream.Create("C:\test.bin", fmOpenReadWrite);
 F.Position := 0;
 F.Read(len, 1);
 SetLength(S, len);
//  for i := 1 to len         //это пока заремил, что то сам пытался дописать
//   do F.Read(S[i], 1);
 F.Read(S[1], len);
 F.Free;
 Memo3.Lines.Text:=s;
end;


 
Рамиль ©   (2006-03-26 13:50) [12]


> //а вот тут тоже нормально :),
> //но читает только из любого файла только первые ~100 (байт
> или символов)
> //а хотелось бы, если файл 15 кб, весь его и считать :(

Не, ну если ты пишешь сначала
F.Write(len, 1);
Причем len = 100
А потом
F.Read(len, 1);
SetLength(S, len);
F.Read(S[1], len);
Причем не соизволив проинициализировать len.
Что ты вообще хочешь?


 
.Кирилл ©   (2006-03-26 16:46) [13]

Тогда опять вопрос, как проинициализировать len? Прировнять ее к размеру файла в байтах?


 
Рамиль ©   (2006-03-26 17:10) [14]

Ну, если хочешь весь забрать, то, в принципе да. Но это если файл просто текстовый.
Но, если ты сам пишешь
F.Write(len, 1);А потом спрашиваешь

> И ещё вопрос возник, в начале и конце файла вставляются
> различные символы, и если читать с помощью Memo3.Lines.LoadFromStream(F);
> , эти символы показываются, хотя их я не формировал,

То это уже начинает наводить на мысль, что ты не понимаешь, что делаешь.


 
Рамиль ©   (2006-03-26 17:13) [15]

Да, еще, почему
F.Write(len, 1);
если len описано как Word?


 
DevilDevil ©   (2006-03-27 11:54) [16]

Да, еще, почему
F.Write(len, 1);
если len описано как Word?


в том то и дело, что len у тебя теперь занимает 2 байта, следовательно надо просто заменить единицу на 2 :)

а по поводу добавления, в текстовых файлах, чтобы "отделять" одну строку
от другой, в файле в конце каждой строки добавляются два символа с кодами 13 и 10 только не помню в какой последовательности



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

Текущий архив: 2006.04.30;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.042 c
2-1145082835
Mozart
2006-04-15 10:33
2006.04.30
не могу отправить e-mail :(


15-1144384396
Хозяин
2006-04-07 08:33
2006.04.30
11-12 апреля по 1 каналу


6-1137077876
Fantom
2006-01-12 17:57
2006.04.30
Помогите решить проблему WebBrowser.


2-1144819651
Leshas
2006-04-12 09:27
2006.04.30
Обработка ошибок


2-1145030740
GeoNew
2006-04-14 20:05
2006.04.30
Запуск приложения