关于流的应用遇到了困难,请高手指点(100分)

  • 主题发起人 主题发起人 xxljishiben
  • 开始时间 开始时间
X

xxljishiben

Unregistered / Unconfirmed
GUEST, unregistred user!
昨日看了 陈前辈的关于流的应用的文章,于是今天着手学习流的应用http://delphibbs.2ccc.com/keylife/iblog_show.asp?xid=2762
首先是exe文件加密器的制作。
加密过程如下:
//制作head.exe作为头文件, 就是用来输入被加密文件密码的对话筐
//把head.exe 以及被加密的exe文件用流对象方式打开。
//通过copyfrom方法,把被加密文件与head文件流合并。
//在流的末尾加入 4 个字节,用来记录被加密文件的长度,以便读出。
~~~~~~~~~~~
以上是陈老师举例中提到的,由于为了描述方便,他没有讲关于密码的存储问题, 而是用了一个固定密码来简要说明。于是,我又给加上如下内容
~~~~~~~~~~~
//在流的末尾用Twriter对象的writestring方法写入密码
//在流的末尾再加入 4 个字节记录密码的长度

~~~~~~~~~~~~~~~~~~~
解密过程如下
//读出密码长度
//读出密码,判断记录的密码与当前输入密码是否一致
//如果密码正确,读出文件长度,
//然后读出文件并保存。
~~~~~~~~~~~~~~~~~~~
问题如下:我用 Twriter 对象的方法写入密码
mywriter:=Twriter.Create(target,1024)
//写入密码
mywriter.WriteListBegin;
mywriter.WriteString(password);
mywriter.WriteListEnd;
用 Treader 对象的 方法读出密码时出错。
m_pass:=treader.Create(source,1024) ;
m_pass.ReadListBegin;
result:=m_pass.ReadString;
~~~~~~~~~~~~~~~~ 这是相对严格按照树上介绍的Tfliter的方法进行的。
以下程序方法也行不通。
mywriter:=Twriter.Create(target,1024)
//写入密码
mywriter.WriteString(password);
用 Treader 对象的 方法读出密码时出错。
m_pass:=treader.Create(source,1024) ;
result:=m_pass.ReadString;
 
在线苦等答案啊,各位前辈指点~!
 
请问读取出错,出的是什么错呢
 
我用方法1 调试 ,在 m_pass.ReadListBegin
句出错,
用方法2调试 在result:=m_pass.ReadString;句出错
其错误提示均为: invalid property value
 
我看的用Twriter ,Treader的例子中都是用的
writelistbegin;
for i:= 1 to memo1.lines.count-1 do
writestring(memo1.lines);
writelistend;
读取时:
readlistbegin;
while not endoflist do
memo1.lines.add(readstring);
 
按照我的理解,似乎我用的方法没有什么错误,还请高手指点小弟啊
 
我暂时也看不出错误,因为我是低手,呵呵。期待一下
在写和读之前都把Position属性置为0不知道行不行。
 
错误提示都是非法(无效)的属性值。
印象中TReader/TWriter主要用来读写Component,楼主何不考虑直接用内存流来写呢,那样肯定不会有错的。
 
先谢谢iseek的提示, 我会试一下 。不过, TReader/TWriter我所知的介绍如下:TReader和TWriter都有许多方法(Methods),两者配合使用可方便读出和保存不同数据类型,如:字符类型、布尔类型、货币类型、日期类型、浮点类型、整数类型、字符串类型。

再者,我曾用读写文件流的方式
i:=sizeof(my_passwordsize); //取出密码长度的字节数 4个字节
source.Seek(-i,soFromEnd)
//把指针移动到密码长度的位置
source.ReadBuffer(my_passwordsize,sizeof(my_passwordsize))
//读出密码长度
i:= my_passwordsize+sizeof(my_passwordsize)

source.Seek(-i,soFromEnd)
//把指针移动到密码存放位置(从末尾移动 密码长度就加上 密码长度的长度 位置)
source.ReadBuffer(my_password,my_passwordsize)

得出的结果也是无效的 ,用单步调试的结果时my_password 值很奇怪 “ /0,/0,/0.....‘这种形式,具体值记不清了,第一次用的时候是这样子的。不过当时用的是文件流,不是内存流,个人认为似乎区别不大·
 
当然, 此前写数据的时候也是用writebuffer写入的
 
为什么没有合适的回答啊?
 
我习惯用内存流.下面写个例子你看看.你自己可以运行一下.

procedure TForm1.Button1Click(Sender: TObject);
var n:longint;
ms:TMemoryStream;
ps:string;
buffer:pchar;
begin
ps:='jblefqgwrjklwegnoibeqebvfa';
buffer:=pchar(ps);
n:=SizeOf(buffer);
ms:=TMemoryStream.Create;
try
ms.WriteBuffer(buffer,n);
ms.Write(n,SizeOf(longint));
ms.SaveToFile('c:/test.xxx');
finally
ms.Free;
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var m:longint;
ms:TMemoryStream;
buffer:pchar;
begin
ms:=TMemoryStream.Create;
try
ms.LoadFromFile('c:/test.xxx');
ms.Seek(-SizeOf(longint),soFromEnd);
ms.Read(m,SizeOf(longint));
ms.Seek(-(m+SizeOf(longint)),soFromEnd)
//这里实际上到了流头
ms.ReadBuffer(buffer,m);
showmessage(strpas(buffer));
finally
ms.Free;
end;
end;
 
强烈建议用内存流
 
原来内存流和文件流差别很大啊, 读出来的内容终于不再是无效值或者空值了,终于有内容了,虽然内容是乱码~!
感谢iseek的代码,今天明天调试成功我散分~!
 
多人接受答案了。
 
后退
顶部