流与流操作符(转)

流化
*流对数据(通常是对象)的外部存储进行抽象
*流化API是抽象的
 - 它提供从存储读取数据和向存储写入数据的接口,但是不关心存储是什么
 - 定义于s32std.h,文件流定义于s32file.h
  · 该头文件与estor.lib相联
*基于两个关键概念
 - 流
 - 流操作符


*数据结构(比如对象)的外部表示,其形式是二进制数据序列
*通过读/写流访问
*设计用于流实现的C++类
 - ExternalizeL()
  ·外部化流状态
 — InternalizeL()
  ·内部化流状态
*优点
 - 更适用于原始文件操作
 - 使用起来更加容易

外部化
*外部化对象的过程也就是将该对象的数据写入流中
*对于一个类的实例,该过程包括将其数据成员和组件外部化到流中
* 该过程封装在该类的成员函数ExternalizeL()中
*使用类RWriteStream的写入流接口
 - 允许ExternalizeL()将对象数据写入流中,而不关心流的具体实现方式
*类一般按照如下的方式定义ExternalizeL()函数
void ExternalizeL(RWriteStream& aStream) const;


写入流
*该操作由抽象类RWriteStream表示
 - 提供必需的接口,以实现外部化到流的操作
*RFileWriteStream 继承自RWriteStream,并且提供关联到文件的接口
 - 也存在其它的具体实现,比如RStoreWriteStream
*RWriteStream 提供对如下对象外部化的支持
 - TInt,TUint,TReal和TReal64类型
 - 描述符的内容
 - 来自于开启的读取流对象的数据,类型为RReadStream
*直到调用RWriteStream::CommitL()将流缓冲写入流,流的写 入操作才执行

 
写入流-示例
*使用RFileWriteStream::Create()创建文件
*使用 RFileWriteStream::Open()打开已经存在的文件

RFs& fs = CCoeEnv::Static()->FsSession();

RFileWriteStream writeStream;
User::LeaveIfError(writeStream.Create(fs,KTxtFileName,EFileWrite));

writeStream.PushL(); /压入清理栈

iObject.ExternalizeL(writeStream);

/清理工作
writeStream.CommitL();
writeStream.Pop();
writeStream.Release();


内部化
*内部化一个对象的过程也就是将该对象的数据从流中读出
*对于一个类的实例,该过程包括将其数据成员和组件从流中读 出
 - 内部化的顺序和外部化的顺序相同
*该过程通过该类的InternalizeL()成员函数封装
*使用读取流接口类 RReadStream
 - 允许函数InteranlizeL()从流中读取对象的数据,而不用考虑流的具体实现
*类通常按照如下的方 式定义InternalizeL()
void InternalizeL(RReadStream& aStream);

读取流
*由抽象类RReadStream表示
 - 提供从流中内部化的必要接口
*RFileReadStream继承自 RReadStream,提供与文件关联的接口
 - 也存在其它形式的具体实现,比如RStoreReadStream
*RReadStream 针对如下数据提供内部化的支持
 - TInt,TUint,TReal和TReal64类型
 - 描述符的内容


读取流-示例
*使用RFileReadStream::Open()打开文件
RFs& fs = CCoeEnv::Static()->FsSession();

RFileReadStream readStream;
User::LeaveIfError(readStream.Open(fs,KTxtFileName,EFileRead));

readStream.PushL();/压入清理栈

iObject.InternalizeL(readStream);

/清理工作
readStream.Pop();
readStream.Release();


流操作符
*有两种模板化的流操作符:operator<<和operator>>
*用于外部化和 内部化各种类型的数据
*使用与C++输入输出流相类似的语法
*该操作符的实现取决于其调用对象的类型

/可以使用写入流将一个对象外部化到流中
writeStream << object;
...
/此后,还可以 通过读取流将该数据内部化
readSteam >> object;

标准类型和类
*存储框架为外部化和内部化操作符提供了必要的实现,包括
 - 基本类型,比如TInt8,TUint8,TReal32 等等
 - 图形API类,比如TPoint,TSize和TRect
 - UID操作API类,比如TUid
 - 动态缓冲API类,比如CBufFlat和CBufSeg
*针对内置类型和类使用流操作符时
 - << 操作符解析为与内置类型或类相关联的RWriteStream函数
  ·比如 RWriteStream::WriteInt8L(TInt aValue) 等等
 - >> 操作符解析为与内置类型或类相关联的RReadStream函数
  ·比如RReadStream::ReadInt8L()等等

可序列化类
*可序列化类是定义和实现ExternalizeL()与InternalizeL()的类
*对于这种类,存储框架
 - 通过调用该类的ExternalizeL()成员函数来实现操作符 <<
 - 能过调用该类的InternalizeL()成员函数来实现操作符 >>
 
 例如iObj是可序列化类的对象
 iObj.ExternalizeL(writeStream)
 等 同于
 writeStream << iObj

 iObj.InternalizeL(readStream)
 等同于
 readStrem >> iObj

序列化TInt
*TInt是特殊的情况
 - 定义一个最小尺寸(所占空间)
 - 实际尺寸是由平台决定的
*不能使 用操作符<<或>>来序列化TInt
*必须使用函数来指定外部尺寸

非类类型
*比如枚举类型
*对于非类类型,需要定义和实现特定的操作符
 - 操作符定义必须和模板定义一致
*举例来 说,对于枚举类型TXxx,操作符应该按照如下的方式进行实现
RWriteStream& operator << (RWriteStream& aStream, const TXxx& anXxx)
{
 aStream WriteInt8L(anXxx);
 return aStream;
}
RReadStream& operator >> (RReadStream& aStream, TXxx& anXxx)
{
 anXxx = TXxx(aStream.ReadInt8L());
}

不可序列化类
*该类不定义和实现ExternalizeL()与InternalizeL()函数
*通过定义和实现一些额外的全局 函数,仍可以对该类进行序列化操作
*实际上,为某个类定义和实现ExternalizeL()与InternalizeL()更加简单
* 但是,在少数情况下,不需要定义该函数,比如,移植类的时候
*所有新建的类应该包含该函数

外部化描述符
*使用RWriteStream类的WriteL()函数
 - 只将描述符的内容写入流中
 - 它们并不会写入任何的长度信息
*使用模板化的流操作符<<
 - 由存储框架实现,将描述符的内容和长度都写入流中
 - 更适用于描述符,因为可以很方便地进行内部化
  ·对应的操作符>>
  ·重载HBufC::NewL()或 HBufCL::NewLC()可以将读取流作为参数

内部化描述符
*使用RReadStream类的Real()成员函数
 - 假设流中只包含描述符的内容
*使用模板化的流操 作符>>
 - 由存储框架实现,从流中读取描述的内容和长度
 - 重载HBufC::NewL()或HBufC::NewLC()可以将读取流作为参数
 - 在从流中内部化之前,需要分配堆描述符
*最后 两项的前提假设是描述符是使用模板化的操作符<<进行外部化的

内部化不可修改的描述符
*不能直接将数据读取写入不可修改的描述符中(TBufC,TPtrC,HBufC):
 - 不可修改的API,故没有重载的>>操作符
 - 使用::Des()创建可修改的描述符
 - 使用可修改的描述符来访问不可修改的描述符拥有的内存
 TBufC iDataItem1;
 TPtr modifiableDataItem1 = iDataItem1.Des();
 aStream >> modifiableDataItem1;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Verilog中,操作符>>和<<用于将数据打包成比特。>>操作符将数据从左至右换为,而<<操作符将数据从右至左换为。可以指定一个片段宽度,将源数据按照这个宽度分段后再换为。不能直接将比特结果赋给非合并数据,而应该使用操作符将比特拆分到非合并数组中。\[1\] streaming_concatenation语法规定了操作符的使用方式,其中stream_operator可以是>>或<<,slice_size可以是简单类型或常量表达式,stream_concatenation表示多个表达式的连接,stream_expression表示表达式和可选的数组范围表达式的组合。\[2\] 在Verilog中,操作符的使用可以根据需要进行灵活的配置。可以根据需要选择不同的位宽、字节顺序和数据类型进行操作。\[3\] #### 引用[.reference_title] - *1* [System Verilog 操作符](https://blog.csdn.net/qq_31348733/article/details/100380245)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [#systemverilog# 关于操作符>>和引发的思考](https://blog.csdn.net/qq_16423857/article/details/131096576)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值