关于 datasnap Stream的英文博客能容
转载:http://blogs.embarcadero.com/jimtierney/2009/04/06/31461/
DataSnap Server Method Stream Parameters
This is a continuation of my posts on DataSnap server method parameters and return types. This post is about TStream and TDBXStreamValue. The sample client and server projects that go with this post can be downloaded here: http://cc.embarcadero.com/item/26854
See my earlier posts on “Basic” and “Basic DBXValue” types. I’ve yet to post about TDBXConnection, TDBXConnectionValue, TDBXReader, TParams, and TDataSet. However, TDataSet is demonstrated in the sample projects.
| Basic | Basic DBXValue | Collection | Connection | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
|
|
The following table summarizes differences between TStream and TDBXStreamValue types:
| Supports null values | Declaration | Accessing Values | Proxy generator | ||||
|---|---|---|---|---|---|---|---|
| Default parameter direction | Other parameter directions | function result type | Get | Set | |||
| TStream | No |
in |
in/out: usevar keyword out: use outkeyword |
Yes |
lhs := AParameter | AParameter := rhs |
Yes |
| TDBXStreamValue |
Yes |
in/out |
None |
No |
AParameter.IsNull lhs:=AParameter.GetStream(InstanceOwner) | AParameter.SetNull AParameter.SetStream(rhs, InstanceOwner) |
No |
Supports null values
The TDBXStreamValue type has an IsNull property and a SetNull method. Use this type instead of TStream a parameter value can be null/nil, in some cases.
Declaration
The var and out keywords can’t be used to specify the parameter direction of a TDBXStreamValue parameter. The direction is always in/out. A TDBXStreamValue type can’t be used as a function result.
Proxy Generator
The RAD Studio 2007 client proxy generator does not work properly for server methods with TDBXStreamValue parameters. So you will need to hand code the client code or correct the generated proxy. The sample client has hand corrected proxy methods that look like this.
function TTestStreamValueClient.Echo(var I: TStream): TStream;
begin
if FEchoCommand = nil then
begin
FEchoCommand := FDBXConnection.CreateCommand;
FEchoCommand.CommandType := TDBXCommandTypes.DSServerMethod;
FEchoCommand.Text := 'TTestStreamValue.Echo';
FEchoCommand.Prepare;
end;
if I = nil then
FEchoCommand.Parameters[0].Value.SetNull
else
FEchoCommand.Parameters[0].Value.SetStream(I, FInstanceOwner);
FEchoCommand.ExecuteUpdate;
if FEchoCommand.Parameters[0].Value.IsNull then
I := nil
else
I := FEchoCommand.Parameters[0].Value.GetStream(FInstanceOwner);
Result := FEchoCommand.Parameters[1].Value.GetStream(FInstanceOwner);
end;
This client method works with a server method declared as follows:
function Echo(I: TDBXStreamValue): TStream;
Calling a server method with a TDBXStreamValue parameter is the same as calling a server method with an TStream parameter, except that you can use SetNull and IsNull methods to work with null values.
For example, compare the following server method declaration and client method implementation to the previous example:
function Echo(I: TStream): TStream;
function TTestStreamClient.Echo(I: TStream): TStream;
begin
if FEchoCommand = nil then
begin
FEchoCommand := FDBXConnection.CreateCommand;
FEchoCommand.CommandType := TDBXCommandTypes.DSServerMethod;
FEchoCommand.Text := 'TTestStream.Echo';
FEchoCommand.Prepare;
end;
FEchoCommand.Parameters[0].Value.SetStream(I, FInstanceOwner);
FEchoCommand.ExecuteUpdate;
Result := FEchoCommand.Parameters[1].Value.GetStream(FInstanceOwner);
end;
Accessing Values
The GetStream and SetStream methods have an InstanceOwner parameter. Passing True indicates that DBX owns the stream and will free it. Passing False indicates that the caller owns the stream. To control how the generated proxy classes call SetStream and GetStream, there is an AInstanceOwner parameter on the proxy class constructor:
constructor TTestStreamClient.Create(ADBXConnection: TDBXConnection; AInstanceOwner: Boolean);
The other constructor is equivalent to passing AInstanceOwner as True.
constructor TTestStreamClient.Create(ADBXConnection: TDBXConnection);
Sample Client And Server Applications
The sample server has a few simple server methods for passing values (including null).
{$METHODINFO ON}
TTestCollection = class(TComponent)
strict protected
procedure LogMessage(const AMessage: string);
public
// Server method to get the parameter type names
procedure GetTypeNames(I: T; ADeclaredName, AActualName: TDBXStringValue);
end;
{$METHODINFO OFF}
TTestStream = class(TTestCollection)
public
function Echo(I: TStream): TStream;
procedure Copy(I: TStream; out J: TStream);
procedure Swap(var I: TStream; var J: TStream);
end;
TTestStreamValue = class(TTestCollection)
public
function Echo(I: TDBXStreamValue): TStream;
procedure Copy(I: TDBXStreamValue; J: TDBXStreamValue);
procedure Swap(I: TDBXStreamValue; J: TDBXStreamValue);
function IsNull(I: TDBXStreamValue): Boolean;
procedure SetNull(I: TDBXStreamValue);
end;
The sample client tests the server methods by calling them with sample values and verifying the results (e.g; comparing streams). TMemoryStream is used to pass short streams and TFileStream to pass long streams. Here is a screen shot of the running server and client:

The following table shows the parameter types and return types demonstrated in the sample client and server:
| Type | Direction | |||
|---|---|---|---|---|
| (default) | var | out | Result | |
| TDBXStreamValue | X (in/out) | |||
| TStream | X (in) | X | X | X |
Stream Usage
Check “Log Stream Usage” to show TStream sizes, type names, creates, destroys, and reads. The results from 4 different test cases are displayed after “Call Server Methods” is clicked.
The screen shot below shows the result from a test case with longer streams. I’ve added highlighting to illustrate these points:
- When the server reads a longer stream passed from the client, round trips are made to the client. This makes it possible to send very large streams to the server without consuming lots of memory.
- When the client reads a longer stream passed from the server, round trips are made to the server. This makes it possible to return very large streams to the client without consuming lots of memory.
- The TStream objects that represent longer client and server streams have a Size of –1, meaning the size is unknown. Rely on the return value of TStream.Read to detect the end of the stream. Also note that some DBX streams such as TDBXStreamReaderStream do not fully support Seek.

That’s all for now.
附件:( http://cc.embarcadero.com/item/26854 链接的文件)
关于 datasnap Stream的英文博客能容的更多相关文章
- 30大最有影响力的Web设计与开发英文博客
1stwebdesigner的创始人Dainis Graveris挑选出30个高质量和具有影响力的Web设计与前端技术博客,其中很多我们都耳熟能详.但这么完整的列表,还是值得收藏的.另外,你大概不会了 ...
- 值得关注的 10 个 Python 英文博客
英文原文:http://pythontips.com/2013/07/31/10-python-blogs-worth-following/ 中文翻译参考: http://python.jobbole ...
- 本文可能是国内第一篇介绍C/4HANA Foundation的中文博客
SAP C/4HANA从去年发布已经过去了一年多的时间,C/4HANA的从业者,对于这五朵云里包含的产品集,想必都有了一些了解. Jerry注意到,SAP C/4HANA Foundation这个概念 ...
- 1、了解计算机与操作系统发展阶段 2、选择一个具体的操作系统,结合计算机与操作系统的发展阶段,详细了解其渊源、发展过程、趋势,整理成简洁美观的图文博客发布。 Windows Mac os x Unix Linux Android 等。
1.了解计算机与操作系统发展阶段 操作系统并不是与计算机硬件一起诞生的,它是在人们使用计算机的过程中,为了满足两大需求:提高资源利用率.增强计算机系统性能,伴随着计算机技术本身及其应用的日益发展,而逐 ...
- 【相关网站 - 02】- Java 好文博客
一.源码分析博客 还有这种操作?浅析为什么要看源码 你觉得什么才是 Java 的基础知识? 1. JDK 2. Mybatis 3. Spring 4. Sring Boot 5. Spring Cl ...
- CasperJS API中文博客链接
http://www.cnblogs.com/reach296/tag/Casperjs/
- Windows Azure中文博客 Windows Azure入门教学系列 (一): 创建第一个WebRole程序
http://blogs.msdn.com/b/azchina/ 本文转自:http://blogs.msdn.com/b/azchina/archive/2010/02/09/windows-azu ...
- 七步,搭建基于Windows平台完美Jekyll博客环境
最近,基于Jekyll新搭建了自己英文博客.整个过程搜索了不少资料,也尝试和过滤了不少工具和插件,最后的效果还是不错的.这里总结一下主要的七个步骤,感兴趣的朋友可以参考一下: 第一步,安装Ruby开发 ...
- 对写博客的n种思考
喜欢才能坚持 开始写博客的原因非常功利,功利到不好意思说. 反正你们也懂的,就那么几种. 问题是,如果心态一直这么功利,而写博客的前期回报几乎为零,情绪会变得沮丧,不知如何继续. 不过后来想想,其实做 ...
随机推荐
- Linq之扩展方法
目录 写在前面 系列文章 扩展方法 总结 写在前面 上篇文章介绍了隐式类型,自动属性,初始化器,匿名类的相关概念,及通过反编译的方式查看了编译器帮我们做了那些事.本篇文章将介绍扩展方法的知识点,及如何 ...
- Bootstrap3.0学习第十四轮(分页、徽章)
详情请查看http://aehyok.com/Blog/Detail/21.html 个人网站地址:aehyok.com QQ 技术群号:206058845,验证码为:aehyok 本文文章链接:ht ...
- javascript继承(八)-封装
这个系列主要探讨的是javascript面向对象的编程,前面已经着重介绍了一下js的继承,下面想简单的说一下js如何实现封装的特性. 我们知道面向对象的语言实现封装是把成员变量和方法用一个类包围起来, ...
- 【转】document.documentElement和document.body的区别
转自:http://www.cnblogs.com/ckmouse/archive/2012/01/30/2332070.html 网页中获取滚动条卷去部分的高度,可以通过 document.body ...
- .net架构设计读书笔记--第三章 第9节 域模型实现(ImplementingDomain Model)
我们长时间争论什么方案是实现域业务领域层架构的最佳方法.最后,我们用一个在线商店案例来说明,其中忽略了许多之前遇到的一些场景.在线商店对很多人来说更容易理解. 一.在线商店项目简介 1. 用例 ...
- Cellphone Typing 字典树
Cellphone Typing Time Limit: 5000ms Memory Limit: 131072KB This problem will be judged on UVA. Ori ...
- js常用插件
1.jQuery Shortcuts 是个超轻量级的方法,使用 jQuery 来绑定快捷键(热键). 2.Underscore封装了常用的JavaScript对象操作方法,用于提高开发效率. 3.Kn ...
- 【POJ 3020】Antenna Placement(二分图匹配)
相当于用1*2的板覆盖给定的h*w的格子里的点,求最少的板.可以把格子相邻的分成两个集合,如下图,0为一个集合,1的为一个,也就是(行数+列数)为奇数的是一个集合,为偶数的为另一个集合.1010101 ...
- spring - ioc和aop
1.程序中为什么会用到spring的ioc和aop 2.什么是IOC,AOP,以及使用它们的好处,即详细回答了第一个问题 3.原理 关于1: a:我们平常使用对象的时候,一般都是直接使用关键字类new ...
- 【SDOI2009】解题汇总
又开了波专题,感觉就和炉石开冒险一样...(说的好像我有金币开冒险似的) /---------------------------------------------/ BZOJ-1226 [SDOI ...