关于写入Stream的问题(60分)

  • 主题发起人 主题发起人 willrain
  • 开始时间 开始时间
W

willrain

Unregistered / Unconfirmed
GUEST, unregistred user!
var
buf : string;
aStream: TMemoryStream;
begin
aStream = TMemoryStream.create;
buf := 'my test stream';
aStream.Write(Buf[1], Length(Buf));
//为什么不是aStream.Write(Buf, Length(Buf))呢???
...
...
aStream.Free;
end;
 
aStream.Write(Buf, Length(Buf));
可以啊!
 
同意小笨蹦,而且我认为最好的办法是楼上的写法!!!
 
我想知道这两种方法的区别?
 
我帮你大致地查阅了一下,WriteBuffer实际上是调用了Write的,前者如果没有把所要求的字节
写入,就会产生一个EWriteError异常,而后者不会。
 
存字符串时应先存入其长度,//否则读的时候就:)
如:
var
buf : string;
aStream: TMemoryStream;
begin
aStream = TMemoryStream.create;
buf := 'my test stream';
aStream.Write(Length(Buf), Length(integer))
aStream.Write(Buf[1], Length(Buf));
...
...
aStream.Free;
end;
 
任豆豆:
我要对你说声“对不起”,因为前几天,你回答了我的一个问题,当时,我没给你加分,
但后来仔细一看,你说的是对的,也应该给你加分的,以后有机会给你补上
 
to 小笨苯:
这么客气^-^
 
aStream.Write(Buf[1], Length(Buf));
从表面上看只写一个字符Buf[1],而实际上却写入了整个buf,
难道Buf[2],buf[3]...都自动写进去?
在delphi的关于write的帮助里好象没这个说法。
 
Buf[1],这种用法应该这样去理解,如果你了解C/C++语言的话,更容易理解
就是说:我们平时使用字符串,都是仅仅使用它的名字,
比如:str: string;
我们只使用str,就代表这个整个的字符串,这是因为str代表了这个字符串的首地址。
那么str[1]是这个字符串的第一个字符,也可以说是第一个字符的地址,一个字符串
的首地址也就是第一个字符的地址,所以,
aStream.Write(Buf[1], Length(Buf));
aStream.Write(Buf, Length(Buf));
是一样的。但
aStream.Write(Buf[2], Length(Buf));就不对了。
我个人认为,还是这样写比较好aStream.Write(Buf, Length(Buf));
 
非常感谢!加分!
 
willrain:
>>我个人认为,还是这样写比较好aStream.Write(Buf, Length(Buf));
我上面说的其他都正确,而这句话暂且不能认为是对的,以后我研究出来,再告诉你!

总觉得这40分拿的有点惭愧!刚才又仔细看了一下beta大侠的话,现将初步的结论告诉你,
下面的写法才是最正确的!!你一定要记住!!

procedure MyPro(var Type_1; const Type_2);
对于var或const的无类型参数,如果Type_1或Type_2是指针类型、字符串类型、数组类型...
MyPro(Type_1^, Type_2[1]);
就是传递整个参数的第一个元素的值。
在函数处理时先取地址
MyPro(var Type_1; const Type_2);
var
a, b: PChar;
begin
a := PChar(@Type_1); //先取地址,再转换类型(由于是无类型嘛)
b := PChar(@Type_2);
end;

所以下面的写法都是正确的。而且[法一]和[法二]是可以通用的。

procedure TForm1.Button2Click(Sender: TObject);
var
ms: TMemoryStream;
str_1, str_2: string;
i, str_1_Len, str_2_Len: Integer;
b: Boolean;
begin
str_1 := 'wo shi xiaobenben';
i := 9;
str_2 := '小笨苯';
b := false;

str_1_Len := Length(str_1);
str_2_Len := Length(str_2);

ms := TMemoryStream.Create;

{ 向流中写入数据 }
ms.Write(str_1_Len, sizeof(Integer)); //写入str_1的长度
ms.Write(Pointer(str_1)^, str_1_Len); //写入str_1的内容 [法一]
ms.Write(i, sizeof(i)); //写入i
ms.Write(str_2_Len, sizeof(Integer)); //写入str_2的长度
ms.Write(str_2[1], str_2_Len); //写入str_2的内容 [法二]
ms.Write(b, sizeof(b)); //写入b

{ 先将一些变量清零,这些都是多余的步骤,为的是验证读出的数据是否正确 }
str_1 := '';
i := 0;
str_2 := '';
b := true;
str_1_Len := 0;

{ 从流中读出数据 }
ms.Position := 0;
ms.Read(str_1_Len, sizeof(Integer)); //读出str_1的长度
SetLength(str_1, str_1_Len); //设置str_1长度
ms.Read(Pointer(str_1)^, str_1_Len); //读出str_1的内容
ms.Read(i, sizeof(Integer)); //读出i
ms.Read(str_1_Len, sizeof(Integer)); //读出str_2的长度
SetLength(str_2, str_1_Len); //设置str_2长度
ms.Read(str_2[1], str_1_Len); //读出str_2的内容
ms.Read(b, sizeof(Boolean)); //读出b

ms.Free;

{ 将数据显示 }
Caption := str_1 + ' - ' + IntToStr(i) + ' - ' + str_2;
if b then
Caption := Caption + ' - true'
else
Caption := Caption + ' - false';
end;
 
小笨笨真是热心的好人哦,以后有机会请多指教!
我看许多控件都用这种方法,aStream.Write(Buf[1], Length(Buf))
因此我偏好这一种
 
后退
顶部