怎么得到 内容主编TStream里面的内容

在Dephi中使用TStream读写数据的技巧
在Dephi中提供了一个抽象的数据类型TStream来支持对流式数据的操作。这些数据通常来自文件、数据库、内存对象、OLE对象等,TStream提供了统一、简洁的方法来进行数据的读写。在通常情况下,我们并不需要直接使用TStream类,对流式数据的读写封装在VCL控件的方法中。但是如果这些方法无法满足我们的要求,就需要自己手动控制数据的读写。 一、 TStream的常用的方法和属性:1. function Read(var B Count: Longint): L abstract 2. function Write(const B Count: Longint): L 3. function Seek(Offset: L Origin: Word): L 4. property Position: L 5. property Size: Longint Read,Write,Seek都是纯虚函数,提供了数据读写和定位的抽象的方法。Read方法将数据从Stream中读到Buffer缓冲区中,Write则实现相反的操作,返回值表示实际读写数据的大小。Seek提供了在Stream中移动数据指针的方法。参数Origin可以取soFromBeginning,soFromCurrent,soFromEnd
三个值,Offset是偏移量,返回值是当前Stream数据指针的位置。 Position表示了数据指针在Stream中的位置。这个属性是可读写的,它实际上就是通过调用Seek方法实现的,所以实际使用时使用这个属性更为方便一些。Size属性表示当前Stream的大小,对于不同的Stream,有些时候是只读的。 二、 Stream数据的读写。1. SaveToStream(Stream: TStream ); file://将类中的数据写到Stream的当前位置中 2. LoadFromStream(Stream: TStream); file://从当前位置读入Stream里的数据 实际使用时我们基本上只要使用上面两个函数就可以了。 三、 例子TStream的继承树图如图1所示(略),实际使用时比较常用的是TFileStream,TMemoryStream,TblobStream,就以这三种流举一例说明具体用法。 创建一个窗体Form1,放置三个按钮btnRead,btnInvert,btnSave和一个文件打开对话框OpenDialog1以及数据控件DataSource1,Table1,test. 使用Dephi提供的Database Desktop创建一个表test,表里有一个字段域Image,数据库文件名存为test.db。在窗体上放置一个TDatabase控件dbTest,一个TTable控件Table1,一个DataSource控件DataSource1,一个TDBNavigator控件DBNavigator1。将dbTest与刚才Desktop创建的数据库相连,Table1的TableName属性设为test.db,DataSource1的DataSet属性设为Table1,DBNavigator1的DataSource属性设为DataSource1,VisibleButtons属性前四个设为TRUE。此外,将dbtest的Connected设为TRUE,Table1的Active属性设为TRUE,使得数据库一开始就处于打开状态。 事件代码编写如下: 1. btnRead的Click事件,这里演示了TFileStream的用法。 var MS: TFileSbegin if OpenDialog1.Execute then beginMS:=TFileStream.Create(OpenDialog1.FileName, fmOpenRead);  Image1.Picture.Bitmap.LoadFromStream(MS);  MS.F 2. btnInvert的Click事件,这里演示了TMemoryStream的用法。其中使用了Invert函数,这是一个简单的将图象反色的函数(仅对真彩图象有效),它返回一个指向处理过的图象数据块的指针。 var MS: TMemoryS pImage: begin MS:=TMemoryStream. Image1.Picture.Bitmap.SaveToStream(MS); MS.Position:=0; pImage:=Invert(MS.Memory, MS.size); file://Memory属性是指向实际内存块的指针 MS.Write(pImage^,MS.size); MS.Position:=0;     file://上一行代码使指针移到了Stream末尾,所以要复位 Image1.Picture.Bitmap.LoadFromStream(MS); FreeMem(pImage);  MS.FInvert函数如下:function TForm1.Invert(pImage: size: Integer):var pData, pMem: PC i: Ibegin pMem:=AllocMem(size); CopyMemory(pMem,pImage,size); pData:=pMem+54; for i:=0 to size-54-1 do begin  pData^:=Char(not integer(pData^));  pData:=pData+1;  Result:=pM1. btnSave的Click事件,这里演示了TMemoryStream的另一种用法,将Stream中的数据写到数据库中去。 var MS: TMemorySbegin MS:=TMemoryStream. Image1.Picture.Bitmap.SaveToStream(MS); MS.Position:=0; Table1.A  file://在数据库中添加一条记录 TBlobField(Table1.FieldbyName('image')).LoadFromStream(MS); Table1.P    file://将所作的更新写入数据库4. DBNavigator1的Click事件,这里演示了TBlobStream的用法,使用了和写入时不同的方法来读出数据库的图象数据。 var MS: TSbegin with Table1 do MS:=CreateBlobStream(FieldbyName('image'),bmRead); Image1.Picture.Bitmap.LoadFromStream(MS); MS.F 1、谈Delphi编程中“流”的利用 什么是流?流,简单来说就是建立在面向对象基础上的一种抽象的处理数据的工具。在流中,定义了一些处理数据的基本操作,如读取数据,写入数据等,程序员是对流进行所有操作的,而不用关心流的另一头数据的真正流向。流不但可以处理文件,还可以处理动态内存、网络数据等多种数据形式。如果你对流的操作非常熟练,在程序中利用流的方便性,写起程序会大大提高效率的。 下面,笔者通过四个实例:EXE文件加密器、电子贺卡、自制OICQ和网络屏幕传输来说明Delphi编程中“流”的利用。这些例子中的一些技巧曾经是很多软件的秘密而不公开的,现在大家可以无偿的直接引用其中的代码了。 “万丈高楼平地起”,在分析实例之前,我们先来了解一下流的基本概念和函数,只有在理解了这些基本的东西后我们才能进行下一步。请务必认真领会这些基本方法。当然,如果你对它们已经很熟悉了,则可以跳过这一步。 一、Delphi中流的基本概念及函数声明 在Delphi中,所有流对象的基类为TStream类,其中定义了所有流的共同属性和方法。 TStream类中定义的属性介绍如下: 1、Size:此属性以字节返回流中数据大小。 2、Position:此属性控制流中存取指针的位置。 Tstream中定义的虚方法有四个: 1、Read:此方法实现将数据从流中读出。函数原形为: Function Read(var BCount:Longint):L 参数Buffer为数据读出时放置的缓冲区,Count为需要读出的数据的字节数,该方法返回值为实际读出的字节数,它可以小于或等于Count中指定的值。 2、Write:此方法实现将数据写入流中。函数原形为: Function Write(var BCount:Longint):L 参数Buffer为将要写入流中的数据的缓冲区,Count为数据的长度字节数,该方法返回值为实际写入流中的字节数。 3、Seek:此方法实现流中读取指针的移动。函数原形为: Function Seek(Offset:LOrigint:Word):L 参数Offset为偏移字节数,参数Origint指出Offset的实际意义,其可能的取值如下: soFromBeginning:Offset为移动后指针距离数据开始的位置。此时Offset必须大于或者等于零。 soFromCurrent:Offset为移动后指针与当前指针的相对位置。 soFromEnd:Offset为移动后指针距离数据结束的位置。此时Offset必须小于或者等于零。 该方法返回值为移动后指针的位置。 4、Setsize:此方法实现改变数据的大小。函数原形为: Function Setsize(NewSize:Longint); 另外,TStream类中还定义了几个静态方法: 1、ReadBuffer:此方法的作用是从流中当前位置读取数据。函数原形为: Procedure ReadBuffer(var BCount:Longint); 参数的定义跟上面的Read相同。注意:当读取的数据字节数与需要读取的字节数不相同时,将产生EReadError异常。 2、WriteBuffer:此方法的作用是在当前位置向流写入数据。函数原形为: Procedure WriteBuffer(var BCount:Longint); 参数的定义跟上面的Write相同。注意:当写入的数据字节数与需要写入的字节数不相同时,将产生EWriteError异常。 3、CopyFrom:此方法的作用是从其它流中拷贝数据流。函数原形为: Function CopyFrom(Source:TSCount:Longint):L 参数Source为提供数据的流,Count为拷贝的数据字节数。当Count大于0时,CopyFrom从Source参数的当前位置拷贝Count个字节的数据;当Count等于0时,CopyFrom设置Source参数的Position属性为0,然后拷贝Source的所有数据; TStream还有其它派生类,其中最常用的是TFileStream类。使用TFileStream类来存取文件,首先要建立一个实例。声明如下: constructor Create(const Filename:Mode:Word); Filename为文件名(包括路径),参数Mode为打开文件的方式,它包括文件的打开模式和共享模式,其可能的取值和意义如下: 打开模式: fmCreate :用指定的文件名建立文件,如果文件已经存在则打开它。 fmOpenRead :以只读方式打开指定文件 fmOpenWrite :以只写方式打开指定文件 fmOpenReadWrite:以写写方式打开指定文件 共享模式: fmShareCompat :共享模式与FCBs兼容 fmShareExclusive:不允许别的程序以任何方式打开该文件 fmShareDenyWrite:不允许别的程序以写方式打开该文件 fmShareDenyRead :不允许别的程序以读方式打开该文件 fmShareDenyNone :别的程序可以以任何方式打开该文件 TStream还有一个派生类TMemoryStream,实际应用中用的次数也非常频繁。它叫内存流,就是说在内存中建立一个流对象。它的基本方法和函数跟上面是一样的。 好了,有了上面的基础后,我们就可以开始我们的编程之行了。 ----------------------------------------------------------------------- 二、实际应用之一:利用流制作EXE文件加密器、捆绑、自解压文件及安装程序 我们先来说一下如何制作一个EXE文件加密器吧。 EXE文件加密器的原理:建立两个文件,一个用来添加资源到另外一个EXE文件里面,称为添加程序。另外一个被添加的EXE文件称为头文件。该程序的功能是把添加到自己里面的文件读出来。Windows下的EXE文件结构比较复杂,有的程序还有校验和,当发现自己被改变后会认为自己被病毒感染而拒绝执行。所以我们把文件添加到自己的程序里面,这样就不会改变原来的文件结构了。我们先写一个添加函数,该函数的功能是把一个文件当作一个流添加到另外一个文件的尾部。函数如下: Function Cjt_AddtoFile(SourceFile,TargetFile:string):B var Target,Source:TFileS MyFileSize: begin try Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareExclusive); Target:=TFileStream.Create(TargetFile,fmOpenWrite or fmShareExclusive); try Target.Seek(0,soFromEnd);//往尾部添加资源 Target.CopyFrom(Source,0); MyFileSize:=Source.Size+Sizeof(MyFileSize);//计算资源大小,并写入辅程尾部 Target.WriteBuffer(MyFileSize,sizeof(MyFileSize)); finally Target.F Source.F
except Result:=F E
有了上面的基础,我们应该很容易看得懂这个函数。其中参数SourceFile是要添加的文件,参数TargetFile是被添加到的目标文件。比如说把a.exe添加到b.exe里面可以:Cjt_AddtoFile('a.exe',b.exe');如果添加成功就返回True否则返回假。 根据上面的函数我们可以写出相反的读出函数: Function Cjt_LoadFromFile(SourceFile,TargetFile :string):B var Source:TFileS Target:TMemoryS MyFileSize: begin try Target:=TMemoryStream.C Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone); try Source.Seek(-sizeof(MyFileSize),soFromEnd); Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//读出资源大小 Source.Seek(-MyFileSize,soFromEnd);//定位到资源位置 Target.CopyFrom(Source,MyFileSize-sizeof(MyFileSize));//取出资源 Target.SaveToFile(TargetFile);//存放到文件 finally Target.F Source.F
except Result:= E
其中参数SourceFile是已经添加了文件的文件名称,参数TargetFile是取出文件后保存的目标文件名。比如说Cjt_LoadFromFile('b.exe','a.txt');在b.exe中取出文件保存为a.txt。如果取出成功就返回True否则返回假。 打开Delphi,新建一个工程,在窗口上放上一个Edit控件Edit1和两个Button:Button1和Button2。Button的Caption属性分别设置为“确定”和“取消”。在Button1的Click事件中写代码: var S: begin S:=ChangeFileExt(Application.ExeName,'.Cjt'); if Edit1.Text='790617' then begin Cjt_LoadFromFile(Application.ExeName,S); {取出文件保存在当前路径下并命名"原文件.Cjt"} Winexec(pchar(S),SW_Show);{运行"原文件.Cjt"} Application.T{退出程序} end else Application.MessageBox('密码不对,请重新输入!','密码错误',MB_ICONERROR+MB_OK); 编译这个程序,并把EXE文件改名为head.exe。新建一个文本文件head.rc,内容为: head exefile head.exe,然后把它们拷贝到Delphi的BIN目录下,执行Dos命令Brcc32.exe
head.rc,将产生一个head.res的文件,这个文件就是我们要的资源文件,先留着。 我们的头文件已经建立了,下面我们来建立添加程序。 新建一个工程,放上以下控件:一个Edit,一个Opendialog,两个Button1的Caption属性分别设置为"选择文件"和"加密"。在源程序中添加一句:{$R head.res}并把head.res文件拷贝到程序当前目录下。这样一来就把刚才的head.exe跟程序一起编译了。 在Button1的Cilck事件里面写下代码: if OpenDialog1.Execute then Edit1.Text:=OpenDialog1.FileN 在Button2的Cilck事件里面写下代码: var S:S begin S:=ExtractFilePath(Edit1.Text); if ExtractRes('exefile','head',S+'head.exe') then if Cjt_AddtoFile(Edit1.Text,S+'head.exe') then if DeleteFile(Edit1.Text) then if RenameFile(S+'head.exe',Edit1.Text) then Application.MessageBox('文件加密成功!','信息',MB_ICONINFORMATION+MB_OK) else begin if FileExists(S+'head.exe') then DeleteFile(S+'head.exe'); Application.MessageBox('文件加密失败!','信息',MB_ICONINFORMATION+MB_OK)
其中ExtractRes为自定义函数,它的作用是把head.exe从资源文件中取出来。 Function ExtractRes(ResType, ResName, ResNewName : String): var Res : TResourceS begin try Res := TResourceStream.Create(Hinstance, Resname, Pchar(ResType)); try Res.SavetoFile(ResNewName); Result:= finally Res.F
except Result:=
注意:我们上面的函数只不过是简单的把一个文件添加到另一个文件的尾部。实际应用中可以改成可以添加多个文件,只要根据实际大小和个数定义好偏移地址就可以了。比如说文件捆绑机就是把两个或者多个程序添加到一个头文件里面。那些自解压程序和安装程序的原理也是一样的,不过多了压缩而已。比如说我们可以引用一个LAH单元,把流压缩后再添加,这样文件就会变的很小。读出来时先解压就可以了。另外,文中EXE加密器的例子还有很多不完善的地方,比如说密码固定为"790617",取出EXE运行后应该等它运行完毕后删除等等,读者可以自行修改。 --------------------------------------------------------------------- 三、实际应用之二:利用流制作可执行电子贺卡 我们经常看到一些电子贺卡之类的制作软件,可以让你自己选择图片,然后它会生成一个EXE可执行文件给你。打开贺卡时就会一边放音乐一边显示出图片来。现在学了流操作之后,我们也可以做一个了。 添加图片过程我们可以直接用前面的Cjt_AddtoFile,而现在要做的是如何把图像读出并显示。我们用前面的Cjt_LoadFromFile先把图片读出来保存为文件再调入也是可以的,但是还有更简单的方法,就是直接把文件流读出来显示,有了流这个利器,一切都变的简单了。 现在的图片比较流行的是BMP格式和JPG格式。我们现在就针对这两种图片写出读取并显示函数。 Function Cjt_BmpLoad(ImgBmp:TISourceFile:String):B var Source:TFileS MyFileSize: begin Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone); try try Source.Seek(-sizeof(MyFileSize),soFromEnd); Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//读出资源 Source.Seek(-MyFileSize,soFromEnd);//定位到资源开始位置 ImgBmp.Picture.Bitmap.LoadFromStream(Source); finally Source.F
except Result:=F E
上面是读出BMP图片的,下面的是读出JPG图片的函数,因为要用到JPG单元,所以要在程序中添加一句:uses jpeg。 Function Cjt_JpgLoad(JpgImg:TSourceFile:String):B var Source:TFileS MyFileSize: Myjpg: TJpegI begin try Myjpg:= TJpegImage.C Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone); try Source.Seek(-sizeof(MyFileSize),soFromEnd); Source.ReadBuffer(MyFileSize,sizeof(MyFileSize)); Source.Seek(-MyFileSize,soFromEnd); Myjpg.LoadFromStream(Source); JpgImg.Picture.Bitmap.Assign(Myjpg); finally Source.F Myjpg.
except Result:= E
有了这两个函数,我们就可以制作读出程序了。下面我们以BMP图片为例: 运行Delphi,新建一个工程,放上一个显示图像控件Image1。在窗口的Create事件中写上一句就可以了: Cjt_BmpLoad(Image1,Application.ExeName); 这个就是头文件了,然后我们用前面的方法生成一个head.res资源文件。
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!spark 如何从foreachRDD 获取数据 ?
作者:用户
浏览:1624 次
如何从foreachRDD获取数据?stream.foreachRDD(rdd=&{}###什么叫获取数据?JavaStreamingContextjsc=newJavaStreamingCon
问题描述如何从foreachRDD获取数据?stream.foreachRDD(rdd=&{}解决方案解决方案二:什么叫获取数据?JavaStreamingContextjsc=newJavaStreamingContext(newJavaSparkContext(newSparkConf()),newDuration(1000));JavaDStream&String&dStream=jsc.socketTextStream("localhost",16888);dStream.foreachRDD(newVoidFunction2&JavaRDD&String&,Time&(){@Overridepublicvoidcall(JavaRDD&String&rdd,Timetime)throwsException{rdd.foreach(newVoidFunction&String&(){@Overridepublicvoidcall(Strings)throwsException{System.out.println(System.currentTimeMillis()+":"+s);}});}});jsc.awaitTermination();解决方案三:stream是从kafka消费消息,希望stream.foreachRDD(rdd=&{在一个节点获取所有数据,而不是在每个worker中获得各自的数据,比如,以下可以获得count值,stream.foreachRDD(rdd=&{rdd.collect()valcount=rdd.count()print("linecountis"+count)}问题是:如何获得每个消息的内容,而不仅是count值解决方案四:我用的是scala,java有点看不懂。解决方案五:引用2楼hghdown的回复:stream是从kafka消费消息,希望stream.foreachRDD(rdd=&{在一个节点获取所有数据,而不是在每个worker中获得各自的数据,比如,以下可以获得count值,stream.foreachRDD(rdd=&{rdd.collect()valcount=rdd.count()print("linecountis"+count)}问题是:如何获得每个消息的内容,而不仅是count值stream.foreachRDD(rdd=&{rdd.foreach(val=&{println(val)//你要的单个记录})}解决方案六:这样只能在worker端操作,无法获得并显示数据,如果是:rdd.collect().foreach(line=&{println(line)})则获得如下的结果:consumer.kafka.MessageAndMetadata@10a794c2解决方案七:引用5楼hghdown的回复:这样只能在worker端操作,无法获得并显示数据,如果是:rdd.collect().foreach(line=&{println(line)})则获得如下的结果:consumer.kafka.MessageAndMetadata@10a794c2你打开sparkwebui点击你的Application,在上边点击Executor,随便找个Executor的stdout,println的输出就在那里。获得数据?stream.foreachRDD(rdd=&{rdd.foreach(line=&{println(line.topic)println(line.key)println(line.message)//不都在这了么....})})解决方案八:很感谢@link0007热心回帖。我这里是采用了一个工具来从kafka消费消息:dibbhatt/kafka-spark-consumerhttps://hub.com/dibbhatt/kafka-spark-consumer其用法代码中是这样的:valprops=newjava.util.Properties()kafkaPropertiesforeach{case(key,value)=&props.put(key,value)}valtmp_stream=ReceiverLauncher.launch(ssc,props,numberOfReceivers,StorageLevel.MEMORY_ONLY)tmp_stream.foreachRDD(rdd=&{rdd.collect()//可以得到消息的数目,但不知如何得到数据println("nnNumberofrecordsinthisbatch:"+rdd.count())//这里没有类似line.message的方法})ssc.start()ssc.awaitTermination()采用各种方法得到的数据都是:consumer.kafka.MessageAndMetadata@10a794c2目前我还是不知道如何能或得到数据。这就是我的主要问题。解决方案九:rdd.collect()是把消息都取回到driver了。返回的是一个Arrayvaldata=rdd.collect就行了。rdd.count是另外一个action,又触发了一个job,是分布式count
【云栖快讯】云栖社区技术交流群汇总,阿里巴巴技术专家及云栖社区专家等你加入互动,老铁,了解一下?&&
弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率
40+云计算产品,6个月免费体验
稳定可靠、可弹性伸缩的在线数据库服务,全球最受欢迎的开源数据库之一
云服务器9.9元/月,大学必备豆丁微信公众号
君,已阅读到文档的结尾了呢~~
广告剩余8秒
文档加载中
在dephi中使用tstream读写数据的技巧
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
在dephi中使用tstream读写数据的技巧
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='http://www.docin.com/DocinViewer--144.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口服务热线:
您好,访客
||||||||||
delphi流操作技巧总结_delphi教程
发布时间: 14:34:00&&来源:&&作者:&&点击:487
TMemoryStream的继承关系如下&&&& TObject&&&&&& |&&&& TStream&&&&&& |&&&& TCustomMemoryStream&&&&&& |&&&& TMemoryStream
& 如何使用TMemoryStream?&&&&& 其实TmemoryStream使用就跟TStream 一样&&&& 具体的属性,方法可看帮助。&&& 下举一例:&&&&& 如我想在内存中直接读写一个Bitmap,怎么办?&&&&& TmemoryStream帮了你大忙&&&&& &&&& var&&&&&& BitmapMemoryStream:TMemoryS&&&&&& Bitmap1:TB
&&&& procedure TForm.Button1Click(Sender:TObject);&&&&& begin&&&&&&&& BitmapmemroyStream:=TmemoryStream.C file://建立MemoryStream&&&&&&&& Bitmap1:=TBitmap.C&&&&&&& try&&&&&&&&& Bitmap1.LoadFromFile(d:Bitmap1.bmp);&&&&&&& except&&&&&&&&& ShowMessage(Error On LoadFile bitmap1.bmp);&&&&&&&&&&&&&&& &&& &&& procedure TForm.Button2Click(Sneder:Tobject);&&&& begin&&&&& if Assigned(Bitmap1) then&&&&&&&&& Bitmap1.SaveToStream(BitmapmemoryStream);&&&&&& && procedure& TForm.Button3Click(Sender:TObject);&&&& begin&&&&&& if BitmapMemoryStream&&nil then&&&&&&& begin&&&&&&&& try&&&&&&&&&& BitmapMemroyStream.SaveToFile(Bitmap1.str);& file://内存流保存,大小与&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& file://Bitmap1.bmp一样&&&&&&&& except&&&&&&&&&& showmessage(error on access memory!);&&&&&&&&&&&&&&&&&&&&& procedure TForm.Button4Click(Sender:TObject);&&&& var&&&&&& Buffer:Array[0..53]&&&& begin&&&&& if Assigned( BitmapMemroyStream) then&&&&&&& try&&&&&&&&&& BitmapMemroyStream.Seek(0,soFromBeginning);&&&&&&&&&& BitmapMemoryStream.Read(Buffer,54);&&&&&&&&& if Buffer[0]=B and Buffer[1]=M then& file://改写内存内容&&&&&&&&&&& begin&&&&&&&&&&&&& BitmapMemoryStream.Seek(0,soFromBeginning);&&&&&&&&&&&&& BitmapmemoryStream.Write(ICE,3);& &&&&&&&&&&&&& Button3Click(Sender);//将改写的内容写入文件&&&&&&&&&&&&&&&&&& except&&&&&&&&&& ShowMessage(error On Access memroyStream);&&&&&&&&&&&
& 大家可看到用TMemoryStream对与内存读写多么方便,当然其实用不着先建一Bitmap&& 可以用LoadFromFile直接引导文件,但是如果对于其它的内存流却是可以用上述方法&& 上文只是抛转引玉,其它的一些功能大家可以看帮助,自己琢磨!&& 还有很多其它的流式对象,大致都差不多,一通百通!
如何将一个流的内容写入到剪贴板中,并处理
这个技巧是参考Delphi的剪贴板类的实现来完成的。将一个流的内容放入剪贴板,首先要注册你自已的格式,使用RegisterClipboardFormat()函数然后做下面三步:&&& 1.创建一个内容流,并将内容写进去&&& 2.创建一个全局的内容区,并将流的内容写入&&& 3.调用ClipBoard.SetAsHandle()将内容写入剪贴板
将内容写入剪贴板中var& hbuf&&& : TH& bufptr& : P& mstream : TMemorySbegin& mstream := TMemoryStream.C& try&&& {-- 处理流的代码 --}&&& hbuf := GlobalAlloc(GMEM_MOVEABLE, mstream.size);&&& try&&&&& bufptr := GlobalLock(hbuf);&&&&& try&&&&&&& Move(mstream.Memory^, bufptr^, mstream.size);&&&&&&& Clipboard.SetAsHandle(CF_MYFORMAT, hbuf);&&&&& finally&&&&&&& GlobalUnlock(hbuf);&&&&&&&& except&&&&& GlobalFree(hbuf);&&&&&&&&& finally&&& mstream.F&请注意不要将分配的全局缓冲区释放,这个工作由剪贴板来完成,在读出数据中你应该将它复制后处理。
将剪贴板内容读出来var& hbuf&&& : TH& bufptr& : P& mstream : TMemorySbegin& hbuf := Clipboard.GetAsHandle(CF_MYFORMAT);& if hbuf && 0 then begin&&& bufptr := GlobalLock(hbuf);&&& if bufptr && nil then begin&&&&& try&&&&&&& mstream := TMemoryStream.C&&&&&&& try&&&&&&&&& mstream.WriteBuffer(bufptr^, GlobalSize(hbuf));&&&&&&&&& mstream.Position := 0;&&&&&&&&& {-- 处理流的代码 --}&&&&&&& finally&&&&&&&&& mstream.F&&&&&&&&&&&& finally&&&&&&& GlobalUnlock(hbuf);&&&&&&&&&
在Dephi中使用TStream读写数据的技巧
在Dephi中提供了一个抽象的数据类型TStream来支持对流式数据的操作。这些数据通常来自文件、数据库、内存对象、OLE对象等,TStream提供了统一、简洁的方法来进行数据的读写。在通常情况下,我们并不需要直接使用TStream类,对流式数据的读写封装在VCL控件的方法中。但是如果这些方法无法满足我们的要求,就需要自己手动控制数据的读写。
一、 TStream的常用的方法和属性:---- 1. function Read(var B Count: Longint): L abstract ---- 2. function Write(const B Count: Longint): L
---- 3. function Seek(Offset: L Origin: Word): L
---- 4. property Position: L
---- 5. property Size: Longint
---- Read,Write,Seek都是纯虚函数,提供了数据读写和定位的抽象的方法。Read方法将数据从Stream中读到Buffer缓冲区中,Write则实现相反的操作,返回值表示实际读写数据的大小。Seek提供了在Stream中移动数据指针的方法。参数Origin可以取soFromBeginning,soFromCurrent,soFromEnd 三个值,Offset是偏移量,返回值是当前Stream数据指针的位置。
---- Position表示了数据指针在Stream中的位置。这个属性是可读写的,它实际上就是通过调用Seek方法实现的,所以实际使用时使用这个属性更为方便一些。Size属性表示当前Stream的大小,对于不同的Stream,有些时候是只读的。
二、 Stream数据的读写。---- 1. SaveToStream(Stream: TStream ); file://将类中的数据写到Stream的当前位置中 ---- 2. LoadFromStream(Stream: TStream); file://从当前位置读入Stream里的数据
---- 实际使用时我们基本上只要使用上面两个函数就可以了。
三、 例子---- TStream的继承树图如图1所示(略),实际使用时比较常用的是TFileStream,TMemoryStream,TblobStream,就以这三种流举一例说明具体用法。 ---- 创建一个窗体Form1,放置三个按钮btnRead,btnInvert,btnSave和一个文件打开对话框OpenDialog1以及数据控件DataSource1,Table1,test.
---- 使用Dephi提供的Database Desktop创建一个表test,表里有一个字段域Image,数据库文件名存为test.db。在窗体上放置一个TDatabase控件dbTest,一个TTable控件Table1,一个DataSource控件DataSource1,一个TDBNavigator控件DBNavigator1。将dbTest与刚才Desktop创建的数据库相连,Table1的TableName属性设为test.db,DataSource1的DataSet属性设为Table1,DBNavigator1的DataSource属性设为DataSource1,VisibleButtons属性前四个设为TRUE。此外,将dbtest的Connected设为TRUE,Table1的Active属性设为TRUE,使得数据库一开始就处于打开状态。
---- 事件代码编写如下:
---- 1. btnRead的Click事件,这里演示了TFileStream的用法。
var& MS: TFileSbegin& if OpenDialog1.Execute then& beginMS:=TFileStream.Create(OpenDialog1.FileName, fmOpenRead);&&& Image1.Picture.Bitmap.LoadFromStream(MS);&&& MS.F&
---- 2. btnInvert的Click事件,这里演示了TMemoryStream的用法。其中使用了Invert函数,这是一个简单的将图象反色的函数(仅对真彩图象有效),它返回一个指向处理过的图象数据块的指针。 var& MS: TMemoryS& pImage:begin& MS:=TMemoryStream.& Image1.Picture.Bitmap.SaveToStream(MS);& MS.Position:=0;& pImage:=Invert(MS.Memory, MS.size); &file://Memory属性是指向实际内存块的指针& MS.Write(pImage^,MS.size);& MS.Position:=0;&&&&&&&& &file://上一行代码使指针移到了Stream末尾,所以要复位& Image1.Picture.Bitmap.LoadFromStream(MS);& FreeMem(pImage);&&&& MS.F
&Invert函数如下:function TForm1.Invert(pImage: size: Integer):var& pData, pMem: PC& i: Ibegin& pMem:=AllocMem(size);& CopyMemory(pMem,pImage,size);& pData:=pMem+54;& for i:=0 to size-54-1 do& begin&&& pData^:=Char(not integer(pData^));&&& pData:=pData+1;&& Result:=pM
---- 1. btnSave的Click事件,这里演示了TMemoryStream的另一种用法,将Stream中的数据写到数据库中去。 var& MS: TMemorySbegin& MS:=TMemoryStream.& Image1.Picture.Bitmap.SaveToStream(MS);& MS.Position:=0;& Table1.A&& &file://在数据库中添加一条记录& TBlobField(Table1.FieldbyName(image)).LoadFromStream(MS);& Table1.P&&&&&& file://将所作的更新写入数据库
---- 4. DBNavigator1的Click事件,这里演示了TBlobStream的用法,使用了和写入时不同的方法来读出数据库的图象数据。 var& MS: TSbegin& with Table1 do& MS:=CreateBlobStream(FieldbyName(image),bmRead);& Image1.Picture.Bitmap.LoadFromStream(MS);& MS.F
&&&&&& 全文完,感谢你阅读了这篇文章。本人缺乏可用分了,只好来挣点参与分好兑换。如感觉此文对你有帮助的朋友请投我一票,谢谢。
以上内容由
搜集整理,如转载请注明原文出处,并保留这一部分内容。
  “华夏名网” http://www.sudu.cn 和 http://www.bigwww.com 是成都飞数科技有限公司的网络服务品牌,专业经营虚拟主机,域名注册,VPS,服务器租用业务。公司创建于2002年,经过6年的高速发展,“华夏名网”已经成为我国一家知名的互联网服务提供商,被国外权威机构webhosting.info评价为十大IDC服务商之一。
华夏名网网址导航:
上一篇:下一篇:
(4916次点击) (2768次点击) (4158次点击) (2793次点击) (2370次点击) (3727次点击) (3568次点击) (2358次点击) (2528次点击) (2438次点击)
(3415次点击) (3233次点击) (3244次点击) (3989次点击) (2409次点击) (2321次点击) (3211次点击) (3620次点击) (2352次点击) (2335次点击)
& SUDU.CN 飞数科技 版权所有
电话总机:028-91 94
公司地址:四川省成都市青龙街51号倍特康派大厦10楼5号

我要回帖

更多关于 得到app 破解内容下载 的文章

 

随机推荐