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

Вниз

Как записать в бинарный файл данные 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.01 c
10-1117617459
diwww
2005-06-01 13:17
2006.04.30
Как сохранить экселевский файл?


15-1144614620
Zeqfreed
2006-04-10 00:30
2006.04.30
Что почитать о поиске вхождений по маске?


2-1144951770
mobwar
2006-04-13 22:09
2006.04.30
Проблема кодировки после Copy Paste


4-1139050152
DSKalugin
2006-02-04 13:49
2006.04.30
межпроцессное взаимодейтсвие


1-1143312945
Muhan_
2006-03-25 21:55
2006.04.30
Как программно поменять раскладки клавы с англ. на русскую ...





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