AutoCAD-扩展记录Xrecord

一、简介

           Xrecord(扩展记录)该类的设计就是为了提供更好的存储扩展数据的体验,它不算是一个图形对象,一般与DataBase的【命名字典】或者DBObject对象的【扩展字典】联合使用,实质上这两种字典是一种类型的对象(DBDictionary),只是所属对象不同。Xrecord会作为字典的键值存储相关扩展的信息。Xrecord关联数据的属性是Data,而非XData这是一个需要注意的地方,这里我建议就不要管其XData属性了,它继承自DBobject基类,直接当它不存在,不要有什么心里负担。

官方类型介绍地址:AutoCAD 2022 Developer and ObjectARX Help | Xrecord Class | Autodesk

二、操作

下面我按照一个对象关系读写操作描述一下对Xrecord的读写操作,就先不放代码了

1、NamedDictionary通过key值,或者DbObject通过Extensiondictionary 获取或者创建 DBDictionary

2、DBDictionary通过Key值获取或者赋值Xrecord

3、Xrecord通过对Data的获取和赋值进行数据的维护

4、Xrecord.Data属性通过组码和TypedValue对象关联最终的取值信息。

三、坑点

        很抱歉,扯了很多没用的,现在才进入正题。上面所说内容都是常规操作,可以说是人云亦云。我之所以写这篇文章,是因为我被Xrecord给坑了。Xrecord虽然号称可以存储最大2g的数据,但是落到某个组码上,存储数据的大小是有限制的。

       事情是这样,项目开发中我遇到了这样的需求场景,简单来说就是需要把一个存储了业务数据的Json字符串写入命名字典的Xrecord中随dwg文件保存。很直观的,我就调用上面的读写方法去做了。自测时,使用数据少,相应的Json字符串也就不大,整体还是很流畅的。交付给测试人员时,他们做的数据可没那么扭捏,直接就是粗犷的,结果就是保存之后,扩展数据没存全,然后再次反序列化成Json时就失败了。归根到底就是上面提到的数据被截断的问题。

      我遍寻网络,也没有找到什么有用的信息,史海钩沉,下面引用两个比较正规的描述,来源已不可考(好吧,我承认我懒不想再确认一遍了)。  这些内容非但没帮我解决问题,反而还增加了我的困惑,比如上面说的xrecord对象的组码使用1-369.可我使用的是1000啊,怎么也能存呢?这些就不去细想了。

摘抄:

 注意:在项目开发中,CAD程序文件有可能被杀毒软件误杀掉扩展数据相关文件,建议少用XData,可以用Xrecord,其次XData数据的形式约束和长度约束也不是很便利。

    AcDbXrecord是一种数据存储类,与Xdata类似,但其数据存储量和数据存储类型更多,每个AcDbXrecord对象最多可存储2GB的数据。Xrecord对象的DXF组码范围为1~369。Xrecord存储在一种特殊实体——扩展字典中,而扩展字典可以属于一个实体,这样这个实体就拥有了自定义的扩展数据。

  

        我最终是如何解决Xrecord中字符串被截断的问题呢?将字符串在写入ResultBuffer之前,以合理的大小分割成组,创建同一组码的多个TypedValue值。【合理的大小】可真不是我在卖关子,我是实在不知道这个ExtendedDataAsciiString组码对应的字符到底能存多少。通过一些简单测试,我这个字符串的长度定义成了5k,自认为是一个比较安全的量。ExtendedDataAsciiString既然叫做AsciiString应该是保存的单字节字符串,XRecord的相应的长度限制应该也是按字节限制的,但是C#中的字符串使用Unicode的表示的,这个字符串的长度和统计字节长度得到的长度肯定是很难对齐的。因此5k这个值可能有问题,大概率是没有充分利用存储空间,谁知道呢。

      测试过程:存入100000个a,然后重写读取,能读到34464个a。存入不一样的字符,这个数量会受影响。但总的来说5k应该足够小了。下面附一个分割字符串的方法

 /// <summary>
 /// 将原始字符串按制定数量分组
 /// </summary>
 /// <param name="originString"></param>
 /// <param name="groupSize"></param>
 /// <returns></returns>
 private static List<string> SliceUp(string originString,int groupSize)
 {
     if (string.IsNullOrWhiteSpace(originString))
         return new List<string>();
     List<string> result = new List<string> ();
     var group = originString.Length / groupSize;
     for (int i = 0; i < group; i++)
     {
         result.Add(originString.Substring(i * groupSize, groupSize));
     }
     if(group*groupSize<originString.Length)
     {
         result.Add(originString.Substring(group * groupSize));
     }
     return result;
 }
 
 
 //使用该方法创建ResultBuffer
  ResultBuffer resBuffer = new ResultBuffer();
 var strArray = SliceUp(data, 1024 * 5);
 foreach (var str in strArray)
 {
     resBuffer.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, str));
 }

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值